2010-08-12 38 views
7

Tôi có một số <selects> mà tôi cần phải điền với một số choices phụ thuộc vào người dùng hiện đã đăng nhập. Tôi không nghĩ rằng điều này có thể (hoặc dễ) để làm từ bên trong lớp biểu mẫu, vì vậy tôi có thể để trống lựa chọn và đặt chúng trong chế độ xem thay thế? Hoặc tôi nên dùng cách tiếp cận nào?Django: Đặt các lựa chọn trường từ chế độ xem?

Trả lời

5

Không chắc chắn nếu đây là câu trả lời hay nhất, nhưng trước đây tôi đã đặt lựa chọn trường lựa chọn trong init của biểu mẫu - bạn có khả năng chuyển các lựa chọn của bạn tới hàm tạo của biểu mẫu ...

+0

Hoặc chỉ cần đối tượng người dùng, và phần còn lại tôi có thể làm từ bên trong init. Nhưng làm thế nào để bạn thiết lập các lựa chọn từ bên trong init? Bạn có làm 'self.field = ...' như bình thường, hay bạn chỉ có thể sửa đổi một cách rõ ràng thuộc tính lựa chọn? Bạn có một đoạn mã nhỏ tiện dụng? – mpen

+2

bạn có thể làm một cái gì đó như self.fields ['field_name']. Choice = choice_tuple –

1

Xem xét rằng bạn đã bao gồm người dùng làm thông số, tôi sẽ giải quyết vấn đề này bằng thẻ tùy chỉnh.

Trong ứng dụng/templatetags/custom_tags.py một cái gì đó của bạn như thế này:

@register.simple_tag 
def combo(user, another_param): 
    objects = get_objects(user, another_param) 
    str = '<select name="example" id="id_example">' 
    for object in objects: 
     str += '<option value="%s">%s</option>' % (object.id, object.name) 
    str += '</select>' 
    return mark_safe(str) 

Sau đó, trong mẫu của bạn:

{% load custom_tags %} 
{% special_select user another_param %} 

Thông tin thêm về thẻ tùy chỉnh http://docs.djangoproject.com/en/dev/howto/custom-template-tags/

+1

... cái gì? Bạn có đề xuất tôi thêm các trường bổ sung từ bên trong * mẫu * không? Điều đó thậm chí sẽ không xác nhận, bởi vì chúng không nằm ngoài 'lựa chọn' hợp lệ. Tôi nghĩ rằng các mẫu là nơi cuối cùng bạn muốn làm điều này ... đó là cách tôi chạy vào snag này ở nơi đầu tiên. – mpen

+1

Điều này sẽ hiệu quả, nhưng cá nhân tôi sẽ tránh làm điều đó vì một vài lý do. Nó không phải là DRY - thẻ này xác định lại những gì widget hiện có đã chọn, nó không thể tái sử dụng - cặp này là một quá trình cụ thể để thu thập dữ liệu với một bản trình bày cụ thể của dữ liệu đó, và cuối cùng nó không tận dụng các hình thức django, mà cá nhân tôi thích để xử lý việc nhập dữ liệu. Nhưng vẫn còn, một giải pháp khả thi. –

+1

@Mark Tôi quên nói rằng giải pháp này không dựa trên các biểu mẫu django, bạn sẽ nhận được giá trị từ POST theo cách thủ công. – juanefren

2

Bạn có thể xây dựng hình thức của bạn tự động trong bạn xem (tốt, thực sự tôi muốn giữ mã bên ngoài xem trong chức năng riêng của nó và chỉ cần gọi nó trong xem nhưng đó chỉ là chi tiết)

tôi đã làm nó như thế này trong một dự án:

user_choices = [(1, 'something'), (2, 'something_else')] 
fields['choice'] = forms.ChoiceField(
    choices=user_choices, 
    widget=forms.RadioSelect, 
) 
MyForm = type('SelectableForm', (forms.BaseForm,), { 'base_fields': fields }) 
form = MyForm() 

Rõ ràng, bạn sẽ muốn tạo user_choices tùy thuộc vào người sử dụng hiện tại và thêm bất cứ lĩnh vực bạn cần cùng với sự lựa chọn, nhưng đây là một nguyên tắc cơ bản , Tôi sẽ để phần còn lại làm bài tập đọc.

0

Django tạo các biểu mẫu động - Nó hoạt động !!

Forms.py


class MyForm(forms.Form): 

     """ Initialize form values from views""" 

     select=forms.BooleanField(label='',required=False) 

     field_1=forms.CharField(label='',widget=forms.TextInput(attrs= \ 

        {'size':'20','readonly':'readonly',})) 

     field_2=forms.ChoiceField(widget=forms.Select(), \ 

        choices=((test.id,test.value) for test in test.objects.all())) 



     def __init__(self, *args, **kwargs): 

      super(MyForm, self).__init__(*args, **kwargs) 

      input=kwargs.get('initial',{}) 

      get_field_1_initial_input_from_views=re.sub("\[|\]|u'|'","",str (input.values())) 

      # override field_2 choices based on field_1 input 

      try: 

       # filter choices 

       self.fields[‘field_2'].choices=((test.id,test.value) for test in test.objects.filter (--------))) 

      except: 

       pass 

Views.py


def views_function(request,val): 

     """Dynamically generate input data for formset.""" 

     Initial_data=[] 
     initial_data.append({'field_1':data.info}) 

     #Initializing formset 

     MyFormSet=formset_factory(MyForm,extra=0) 

     formset=MyFormSet(initial=initial_data) 

     context={'formset':formset} 

     if request.method == 'POST': 

      formset=MyFormSet(request.POST,request.FILES) 

      if formset.is_valid(): 

       # You can work with the formset dictionary elements in the views function (or) pass it to 
       #Forms.py script through an instance of MyForm 

       return HttpResponse(formset.cleaned_data) 

     return render_to_response(‘test.html', context,context_instance=RequestContext(request)) 
+2

định dạng của bạn là tất cả hơi say lên, đó là khá quan trọng đối với python – mpen

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