2017-02-13 12 views
0

돈을 목록 템플릿 또는 세부 정보 (읽기 전용) 템플릿으로 표시 할 때 통화 기호가 포함 된 필드 값의 예쁜 버전을 표시하고 싶습니다. "$ 100.00"Django money 필드를 목록 템플릿에서 통화 기호로 나타내고 편집을 위해 소수점 이하를 표시하는 방법은 무엇입니까?

그러나 레코드를 편집하는 중, 통화 기호없이 TextInput 상자에 "100.00"을 표시하려고합니다.

나는 내 장고 응용 프로그램에서 돈을 나타 내기 위해 사용자 정의 models.DecimalField 클래스와 forms.DecimalField 클래스를 만들었습니다.

그래서 템플릿에 필드 값의 대체 버전 (예 :보기에 적합하지만 편집하기에 적합하지 않은 형식)을 사용하는 방법을 찾고 있습니다. 나는 이것을 수행 할 수있는 템플릿 필터가 있다는 것을 알고 있지만 폼의 필드를 반복하고 값을 표시하는 것을 막을 수 있다고 생각합니다.

사용자 정의 필드 클래스에 pretty 속성을 추가 할 수 있다면 템플릿에 존재하는지 확인할 수 있습니다.

class MoneyFormField(forms.DecimalField): 
    def __init__(self, *args, **kwargs): 
     # I plan to add symbol localization code here 
     self.symbol= '$' 

    def prepare_value(self, value): 
     # assign pretty value to an attribute that template can access 
     self.pretty = self.pretty_value(value)    
     try: 
      return round(Decimal(value),2) 
     except: 
      return 0 

    def pretty_value(self, value): 
     if not value: 
      value = 0 
     return self.symbol + str(round(Decimal(value),2)) 

문제는 템플릿의 꽤 값에 액세스하기 위해, 나는()를 호출하는 prepare_value 있도록 먼저 원래 값에 액세스해야한다는 것입니다 : 지금까지 나는이 시도.

나는이 같은 템플릿에 예쁜 값을 출력하려고하면

...

{% for field in payment_form %} 
    {{ field.field.pretty }} {{ field.value }} {{ field.field.pretty }} 
{% endfor %} 

는 예쁜 무시 첫째,하지만 마지막 꽤 인쇄합니다.

나는이 나는이 같은 템플릿에 꽤 값 (또는 거의 존재하지 않는 경우 디폴트 값)을 표시 할 일을 얻을 수있는 경우 :

{% if field.field.pretty %} 
    {{ field.field.pretty}} 
{% else %} 
    {{ field.value }} 
{% endif %} 

누구가를 만들기위한 어떤 제안이 있습니까를 템플릿에서 사용할 수있는 필드의 대체 표현?

TL : DR- 양식 필드의 필드의 값에 액세스하려면 어떻게해야합니까?

답변

0

제가 해결책을 생각해 냈습니다. 그러나 장고와 파이썬에 익숙하지 않아서 불필요하게 지나치게 복잡해질 수 있습니다. 그래서 나는 어떤 의견이라도 듣고 싶다!

요약 : 돈 필드에 목록 및 읽기 전용 세부 정보와 같은 특정 템플릿에서 "100.00"대신 "$ 100.00"으로 돈을 표시 할 수있는 "예쁜"버전이 필요했습니다.

class MoneyField(models.DecimalField): 
    def __init__(self, *args, **kwargs): 
     kwargs['max_digits'] = 13 
     kwargs['decimal_places'] = 4 
     kwargs['default'] = 0 

    def formfield(self, **kwargs): 
     defaults = {'form_class': MoneyFormField} 
     defaults.update(kwargs) 
     return super(MoneyField, self).formfield(**defaults)   

가 여기 내 MoneyFormField 양식 필드입니다 :

나는 내 사용자 지정 양식 필드를 지정하는 돈 모델 필드, MoneyFormField를 만들었습니다.난 그냥 이런 짓을하면

class MoneyBoundField(BoundField): 
    def pretty(self): 
     return self.field.prefix+str(self.value()) 

가 나는 꽤 값을 인쇄 할 수 있습니다 :

class MoneyFormField(forms.DecimalField): 
    def __init__(self, *args, **kwargs): 
     self.widget = MoneyTextInput() # custom widget I'm experimenting with 
     self.prefix = '$'    
     super(MoneyFormField, self).__init__(*args, **kwargs) 

    def get_bound_field(self, form, field_name): 
     return MoneyBoundField(form, self, field_name)   

    def prepare_value(self, value): 
     try: 
      return round(Decimal(value),2) 
     except: 
      return 0 

MoneyBoundField 템플릿에 사용할 수있는 필드의 "꽤"버전을 만드는 것입니다 : 호출에 "get_bound_field"을 참고

{% for somefield in payment_form %} 
    {% if somefield.pretty %} 
     {{ somefield.pretty }} 
    {% else %} 
     {{ somefield.value }} 
    {% endif %}  
{% endfor %} 

하지만 오히려 단지 같은 것을 할 것입니다 : 첫째 꽤 값이 존재하는 경우 확인하고, 그렇지 않은 경우,이 같은 원래의 값을 인쇄하여

{% for somefield in payment_form %} 
    {{ somefield.pretty }} 
{% endfor %} 

그래서 두 줄을 추가하여 boundfields.py의 주요 장고 BoundField 클래스에 꽤 추가했다 :

boundfield.py 
class BoundField(object): 
... 
    def pretty(self): 
     # return default value. Let descendant classes override this function where desired 
     return self.value() 
0

가 여기에 내가했다 또 다른 접근 방식이다. boundfield.py에있는 기본 django BoundField 클래스 정의를 사용하는 대신, 필자는 템플릿 필터를 사용하여 필드를 꽤 아름답게 만듭니다. 필터는 다음을 필드 선택 필드가

  • 경우 필드 사용자 지정 양식 필드가있는 경우, 그것은라는 기능, 사용자 정의 BoundField으로 설명 문자열
  • 로 선택 인덱스 값을 변환 "pretty"는 함수를 호출하고 값을 반환합니다.
  • (주석 처리 된 경우) 해당하는 경우 사용자 정의 formfield 클래스에서 특정 메소드를 호출 할 수 있습니다.

    from django.forms.fields import ChoiceField 
    
    @register.filter 
    def pretty_filter(field): 
        # is this a better way to get the field's value? 
        # field_value = field.form.initial[field.name] 
    
        # get the field's value (for choice fields, this is the integer index used to look up the verbose string in the choices dict) 
        field_value = field.value() 
        if field_value is None: 
         return '' 
        # the the field has 'choices' then return the verbose string for the choice 
        if isinstance(field.field, ChoiceField): 
         for (choices_index, description) in field.field.choices: 
          if choices_index == field_value: 
           return description 
         return '' # no match found 
    
        # # if your model.field's formfield has a function called 
        # # another_custom_function() you can call it this way: 
        # try: 
        #  return field.field.another_custom_function() 
        # except: 
        #  pass 
    
        # attempt to return pretty value if field has th 
        try: 
         return field.pretty() 
        except: 
        # else return default value 
         return field_value 
    
    :이 다음은 그냥이 내 app_filters.py의 코드는

수정되지 않은 필드의 값을 반환 적용되지 않는 경우 양식 필드 클래스

  • 에 BoundField를 정의 할 필요가 없습니다 그런 다음

    class MoneyBoundField(BoundField):  
        def pretty(self): 
         # return $12,345.67 
         return "{}{:,.2f}".format(self.field.prefix,self.value()) 
    
    class MoneyFormField(forms.DecimalField): 
        def __init__(self, *args, **kwargs): 
         self.widget = MoneyTextInput() 
         self.prefix = '$' 
         super(MoneyFormField, self).__init__(*args, **kwargs) 
    
        def get_bound_field(self, form, field_name): 
         return MoneyBoundField(form, self, field_name)  
    

    : 그것은 쉼표를 추가, 그래서

    은 또한 (이것은 지역화를 처리하기 위해 변경 될 수 있습니다) 내 사용자 지정 돈 필드의 꽤 기능을 변경했다 내 템플릿에 나는 이런 식으로 그것을 사용 : 필터 코드의 대부분

    {% load app_filters %} 
    
    {% for item in payment_form %} 
        {{item|pretty_filter}} 
    {% endfor %}     
    

    여기에 사용자 Simple10에서 복사 : https://code.djangoproject.com/ticket/10427#comment:18

    생각이나 의견이 어떤을 공유하세요!