2010-08-12 3 views
7

У меня есть <selects>, что мне нужно заполнить choices, которые зависят от пользователя, который в данный момент вошел в систему. Я не думаю это возможно (или легко) сделать изнутри класса формы, так что я могу просто оставить выбор пустым и вместо этого установить их в представлении? Или какой подход я должен принять?Django: выбор полей из представления?

ответ

5

Не уверен, что это лучший ответ, но в прошлом я установил выбор поля выбора в init формы - вы могли бы передать свои варианты конструктору своей формы ...

+0

или просто объект пользователя, а остальное я мог сделать внутри инициализации. Но как вы устанавливаете выбор изнутри init? Вы делаете 'self.field = ...' как обычно, или можете явно изменить только атрибут выбора? У вас есть небольшой фрагмент кода? – mpen

+2

вы можете сделать что-то вроде self.fields ['field_name']. Choice = choice_tuple –

1

Учитывая, что вы включили пользователя в качестве параметра, я бы решил это с помощью настраиваемого тега.

В вашем приложении/templatetags/custom_tags.py что-то вроде этого:

@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) 

Тогда в шаблоне:

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

Подробнее о пользовательских тегов http://docs.djangoproject.com/en/dev/howto/custom-template-tags/

+1

... что? Вы предлагаете добавить дополнительные поля из * шаблона *? Это даже не подтвердится, потому что они не являются исключением действительных «выборов». Я думаю, что шаблон является последним местом, в котором вы хотите это сделать ... вот как я столкнулся с этой проблемой. – mpen

+1

Это сработает, но я бы лично избегал делать это по нескольким причинам. Это не СУХОЙ - этот тег переопределяет то, что уже делает существующий виджет Select, он не может использоваться повторно - это сопрягает определенный процесс сбора данных с конкретной презентацией этих данных и, наконец, не использует формы django, который я лично люблю для обработки ввода данных. Но все же, жизнеспособное решение. –

+1

@Mark Я забыл сказать, что это решение не основано на django-form, вы должны получить значение из POST вручную. – juanefren

2

Вы можете создать свою форму динамически в вашем представлении (ну, на самом деле, я предпочитаю держать код вне представления в его собственной функции и просто называть его в представлении, но это всего лишь детали)

Я сделал это, как это в одном проекте:

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() 

Очевидно, что вы хотите создать user_choices в зависимости от текущего пользователя и добавлять любые поля вам нужно вместе с выборами, но это основной принцип , Я оставлю все остальное, как упражнение читателя.

0

Django создает динамические формы - это работает!

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

Ваше форматирование все прикручено, что довольно важно для python – mpen

Смежные вопросы