2010-08-05 9 views
110

У меня возникли проблемы с попыткой понять, как создать динамическое поле выбора в django. У меня есть модель создать что-то вроде:Создание динамического поля выбора

class rider(models.Model): 
    user = models.ForeignKey(User) 
    waypoint = models.ManyToManyField(Waypoint) 

class Waypoint(models.Model): 
    lat = models.FloatField() 
    lng = models.FloatField() 

То, что я пытаюсь сделать, это создать выбранное поле Whos значений являются путевыми точками, связанными с этим всадником (который был бы человек вошел в системе).

В настоящее время я переопределение Init в моих формах, как так:

class waypointForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
      super(joinTripForm, self).__init__(*args, **kwargs) 
      self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.all()]) 

Но все, что делает список все путевые точки, они не связаны с каким-либо конкретным наездником. Есть идеи? Благодарю.

ответ

163

вы можете отфильтровать точки маршрута, передавая пользователю в форме инициализации

class waypointForm(forms.Form): 
    def __init__(self, user, *args, **kwargs): 
     super(waypointForm, self).__init__(*args, **kwargs) 
     self.fields['waypoints'] = forms.ChoiceField(
      choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)] 
     ) 

с вашей точки зрения при инициализации формы передать пользователю

form = waypointForm(user) 

в случае модели формы

class waypointForm(forms.ModelForm): 
    def __init__(self, user, *args, **kwargs): 
     super(waypointForm, self).__init__(*args, **kwargs) 
     self.fields['waypoints'] = forms.ModelChoiceField(
      queryset=Waypoint.objects.filter(user=user) 
     ) 

    class Meta: 
     model = Waypoint 
+16

Использование ModelChoiceField, независимо от того, является ли модель ModelForm - она ​​работает и в нормальных формах. –

+8

Что вы делаете, когда хотите получить данные запроса? waypointForm (request.POST) не будет проверяться в первом, потому что данных для проверки против больше нет. – Breedly

+1

@Ashok Как можно использовать виджет CheckboxSelectMultiple в этом случае? Особенно для модели. – wasabigeek

8

У вас есть встроенное решение для вашей проблемы: ModelChoiceField.

Как правило, всегда нужно использовать ModelForm, когда вам нужно создавать/изменять объекты базы данных. Работает в 95% случаев и намного чище, чем создание собственной реализации.

4

Как насчет передачи экземпляра всадника в форму при его инициализации?

class WaypointForm(forms.Form): 
    def __init__(self, rider, *args, **kwargs): 
     super(joinTripForm, self).__init__(*args, **kwargs) 
     qs = rider.Waypoint_set.all() 
     self.fields['waypoints'] = forms.ChoiceField(choices=[(o.id, str(o)) for o in qs]) 

# In view: 
rider = request.user 
form = WaypointForm(rider) 
7

проблема, когда вы делаете

def __init__(self, user, *args, **kwargs): 
    super(waypointForm, self).__init__(*args, **kwargs) 
    self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.filter(user=user)]) 

в запросе обновления, предыдущее значение будет потеряно!

1

Как указано Breedly и Liang, решение Ashok предотвратит получение значения выбора при отправке формы.

Один немного отличается, но все еще несовершенны, способ решить, что будет:

class waypointForm(forms.Form): 
    def __init__(self, user, *args, **kwargs): 
     self.base_fields['waypoints'].choices = self._do_the_choicy_thing() 
     super(waypointForm, self).__init__(*args, **kwargs) 

Это может вызвать некоторые проблемы совпадению, хотя.

0

Под рабочим решением с нормальным полем выбора. Моя проблема заключалась в том, что каждый пользователь имеет свои собственные параметры выбора ПОЛЬЗОВАТЕЛЯ, основанные на нескольких условиях.

class SupportForm(BaseForm): 

    affiliated = ChoiceField(required=False, label='Fieldname', choices=[], widget=Select(attrs={'onchange': 'sysAdminCheck();'})) 

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

     self.request = kwargs.pop('request', None) 
     grid_id = get_user_from_request(self.request) 
     for l in get_all_choices().filter(user=user_id): 
      admin = 'y' if l in self.core else 'n' 
      choice = (('%s_%s' % (l.name, admin)), ('%s' % l.name)) 
      self.affiliated_choices.append(choice) 
     super(SupportForm, self).__init__(*args, **kwargs) 
     self.fields['affiliated'].choices = self.affiliated_choice 
Смежные вопросы