views:

174

answers:

3

I'm having some trouble trying to understand how to create a dynamic choice field in django. I have a model set up something like:

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

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

What I'm trying to do is create a choice Field whos values are the waypoints associated with that rider (which would be the person logged in).

Currently I'm overriding init in my forms like so:

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

But all that does is list all the waypoints, they're not associated with any particular rider. Any ideas? Thanks.

A: 

There's built-in solution for your problem: ModelChoiceField

Generally, it's always worth trying to use ModelForm when you need to create/change database objects. Works in 95% of the cases and it's much cleaner than creating your own implementation.

Alex Lebedev
+2  A: 

you can filter the waypoints by passing the user to the form 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)])

from your view while initiating the form pass the user

form = waypointForm(user)

in case of model form

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
Ashok
Use ModelChoiceField whether or not it's a ModelForm - it works on normal forms too.
Daniel Roseman
A: 

How about passing the rider instance to the form while initializing it?

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) 
Manoj Govindan