views:

373

answers:

2

The particular case I have is like this:

I have a Transaction model, with fields: from, to (both are ForeignKeys to auth.User model) and amount. In my form, I'd like to present the user 2 fields to fill in: amount and from (to will be automaticly set to current user in a view function).

Default widget to present a ForeignKey is a select-box. But what I want to get there, is limit the choices to the user.peers queryset members only (so people can only register transactions with their peers and don't get flooded with all system users).

I tried to change the ModelForm to something like this:

class AddTransaction(forms.ModelForm):
  from = ModelChoiceField(user.peers)
  amount = forms.CharField(label = 'How much?')

  class Meta:
    model = models.Transaction

But it seems I have to pass the queryset of choices for ModelChoiceField right here - where I don't have an access to the web request.user object.

How can I limit the choices in a form to the user-dependent ones?

A: 

In http://www.djangobook.com/en/2.0/chapter07/ , the section Setting Initial Values describes how to use the initial parameter to the Form constructor. You may also do extra stuff in the __init__ method of your derived Form.

Rasmus Kaj
passing initial data would set my select box to specified value - not limit the choices, or modify validation, that i'd get with setting QuerySet in ModelForm definition.
kender
You could inspect the initial parameter (or some other parameter) in your constructor and set limits accordingly?
Rasmus Kaj
+4  A: 

Use the following method (hopefully it's clear enough):

class BackupForm(ModelForm):
    """Form for adding and editing backups."""

    def __init__(self, *args, **kwargs):
        systemid = kwargs.pop('systemid')
        super(BackupForm, self).__init__(*args, **kwargs)
        self.fields['units'] = forms.ModelMultipleChoiceField(
                required=False,
                queryset=Unit.objects.filter(system__id=systemid),
                widget=forms.SelectMultiple(attrs={'title': _("Add unit")}))

    class Meta:
        model = Backup
        exclude = ('system',)

Create forms like this:

form_backup = BackupForm(request.POST,
                         instance=Backup,
                         systemid=system.id)
form_backup = BackupForm(initial=form_backup_defaults,
                         systemid=system.id)

Hope that helps! Let me know if you need me to explain more in depth.

lemonad
Thanks a lot! This really helped.
kender