2010-07-08 45 views
17

Tôi đang viết một ứng dụng Django để sử dụng ở một quốc gia nơi chúng sử dụng dấu phẩy là decimal separator. Tôi có một mô hình có chứa một số django.db.models.DecimalField và tôi sử dụng model forms. Làm cách nào để tạo trường biểu mẫu kết quả bằng cách sử dụng dấu phẩy và chấp nhận dấu phẩy lại từ người dùng?Tạo các biểu mẫu Django sử dụng dấu phẩy làm dấu phân cách thập phân

Tiếp theo advice của jweyrich, tôi đã nâng cấp ứng dụng của tôi từ Django 1,1 đến Django 1.2 và sửa settings.py tôi để chứa những điều sau đây:

LANGUAGE_CODE = 'nb' 
LANGUAGES = (
    ('nb', 'Norwegian'), 
) 
USE_I18N = True 
USE_L10N = True 
DECIMAL_SEPARATOR = ',' 
THOUSAND_SEPARATOR = ' ' 
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.locale.LocaleMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
) 

Theo như tôi có thể thấy, đây là tất cả những gì the documentation cuộc gọi cho. Nó bây giờ làm việc cho các biểu mẫu nếu tôi đặt localization=True trên trường biểu mẫu. Tuy nhiên, nó hoạt động ở cả model forms cũng không phải the admin site.

Tôi đã phát hiện ra một Django ticket và kết quả là Django changeset từ trước bản phát hành 1.2. Nếu tôi hiểu chúng một cách chính xác, nó thường là trường hợp các widget sử dụng tự động định dạng bản địa, nhưng sau khi bản địa hóa bản vá này phải được bật một cách rõ ràng bằng cách đưa tham số từ khóa localization=True vào trường biểu mẫu. Có cách nào để tạo biểu mẫu quản trị viên đặt localization=True trên các trường của họ không?

Trả lời

21

Có, bản địa hóa cần phải được bật rõ ràng cho mọi trường. Đối với một hình thức mô hình (bao gồm cả những người sử dụng trong ứng dụng quản trị), một cách thuận tiện để làm điều này là để phân lớp ModelForm và bật nội địa hóa đối với từng DecimalField:

import django 

class LocalizedModelForm(django.forms.ModelForm): 
    def __new__(cls, *args, **kwargs): 
     new_class = super(LocalizedModelForm, cls).__new__(cls, *args, **kwargs) 
     for field in new_class.base_fields.values(): 
      if isinstance(field, django.forms.DecimalField): 
       field.localize = True 
       field.widget.is_localized = True 
     return new_class 

Sau đó, bạn có thể định nghĩa lớp ModelForm tùy chỉnh của bạn và sử dụng nó trong ứng dụng quản trị:

class FooForm(LocalizedModelForm): 

    class Meta: 
     model = Foo 


django.admin.site.register(Foo, form=FooForm) 
+0

Giải pháp rực rỡ và thanh lịch. – scum

+4

Tôi muốn làm cho nó một mixin: 'LocalizationMixin (đối tượng): ...' và 'FooForm (LocalizationMixin, forms.ModelForm)', vì vậy bạn có thể tiếp tục sử dụng ví dụ: 'FooForm (LocalizationMixin, floppyforms.ModelForm)' – Webthusiast

+0

Điều gì sẽ xảy ra nếu bạn muốn bật tính năng bản địa hóa trực tiếp cho Mô hình? Không phải ModelForms. Trường hợp sử dụng: Xem phản hồi dữ liệu đăng bài yêu cầu AJAX HTTP và muốn lưu trữ dữ liệu đó (chứa các số có dấu phẩy là dấu phân tách nghìn) trong một Mô hình có trường thập phân. Không thể tìm thấy giải pháp cho điều đó. – jorgeas80

8

Phải, điều này có vẻ như một sự cố gây phiền nhiễu mà tôi ngạc nhiên khi chưa có ai báo cáo. Do thay đổi bạn đề cập, việc bản địa hóa phải được bật rõ ràng cho mọi trường trong ứng dụng quản trị hoặc mẫu mô hình của bạn. Cách tốt nhất để làm điều này là xác định một ModelForm tùy chỉnh để sử dụng cả trong quản trị viên và trong ứng dụng của bạn và đặt từ điển widgets để bật tính năng bản địa hóa trên từng trường có liên quan.

class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 
     widgets = { 
      'my_decimal_field': forms.TextInput(attrs={'localization': True}), 
     } 
+3

Điều đó chỉ đặt thuộc tính trong HTML, nhưng bạn đặt tôi đi đúng hướng (một ModelForm tùy chỉnh hóa ra là cách để đi), vì vậy bạn nhận được tiền thưởng. Cảm ơn! Tôi sẽ đăng giải pháp làm việc như một câu trả lời riêng biệt. –

7

trong django> = 1,6 có một giải pháp đơn giản như thế này:

from django.forms import ModelForm 

class YourModelForm(ModelForm): 
    class Meta: 
     model = YourModel 
     localized_fields = '__all__' 

django.admin.site.register(YourModel, form=YourModelForm) 

See the official documentation for a more verbose explanation.

+1

Và đối với forms.Form, 'forms.DecimalField (label = 'Foo', localize = True)' hoạt động. – chhantyal

+0

Dấu ngoặc thừa thừa xung quanh '__all__' – Chris

+0

đã thay đổi dấu ngoặc đơn, nhờ @Chris – zvyn

Các vấn đề liên quan