2010-08-05 27 views
110

Mam problem z próbą zrozumienia, jak utworzyć dynamiczne pole wyboru w django. Mam model założyć coś takiego:Tworzenie pola dynamicznego wyboru

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

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

Co staram się zrobić, to stworzyć whos wybór pól wartości są waypointy związane z tym kierowcy (co byłoby osoba zalogowany).

Obecnie jestem przesłanianie metody init w moich postaciach tak:

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

Ale wszystko, co robi, jest lista wszystkie waypointy, nie są związane z żadnym konkretnym jeźdźca. Jakieś pomysły? Dzięki.

Odpowiedz

163

można filtrować poszczególne punkty trasy, przekazując użytkownikowi formularza init

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

z widoku podczas inicjowania formularz przekazać użytkownikowi

form = waypointForm(user) 

w przypadku wzoru formularza

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

Użyj ModelChoiceField bez względu na to, czy jest to ModelForm - działa również na zwykłych formularzach. –

+8

Co jednak zrobić, gdy chcesz uzyskać dane żądania? waypointForm (request.POST) nie będzie sprawdzany w pierwszym, ponieważ dane do sprawdzenia poprawności są już niedostępne. – Breedly

+1

@Ashok W jaki sposób można użyć widgetu CheckboxSelectMultiple w tym przypadku? Szczególnie dla modelu. – wasabigeek

8

Istnieje wbudowane rozwiązanie Twojego problemu: ModelChoiceField.

Ogólnie rzecz biorąc, zawsze warto próbować użyć ModelForm, kiedy trzeba tworzyć/zmieniać obiekty bazy danych. Działa w 95% przypadków i jest znacznie czystszy niż tworzenie własnej implementacji.

4

Co powiesz na przekazanie instancji Rider do formularza podczas jej inicjowania?

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

problem jest, gdy robisz

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

w żądaniu aktualizacji, poprzednia wartość będzie stracone!

1

Jak wskazał Breedly i Liang, rozwiązanie Ashoka uniemożliwi ci uzyskanie wybranej wartości podczas publikowania formularza.

Jeden nieco inaczej, ale wciąż niedoskonały, sposobem na rozwiązanie, które byłoby:

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) 

Może to powodować pewne problemy zbieżności, choć.

0

Pod rozwiązaniem roboczym z normalnym polem wyboru. Mój problem polegał na tym, że każdy użytkownik ma własne opcje wyboru CUSTOM na podstawie kilku warunków.

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