简体   繁体   中英

Changing queryset of a ModelChoiceField on Django

I am trying to display a dropdownlist showing only some objects in a queryset, but either I am getting an error, or I am displaying none, or I am displaying all.

models.py
class Book(models.Model):
    name = models.CharField(max_length=200, default='')
    owner = models.CharField(max_length=200, default='') 

    def __unicode__(self):
        return self.name

class DropDownList(forms.Form):
    switch = forms.ModelChoiceField(queryset=Book.objects.none().order_by('name'), widget=forms.Select(attrs={"onChange":'submit()'}), required=False, initial=0)

    def __init__(self, u, *args, **kwargs):
        super(DropDownList, self).__init__(*args, **kwargs)    
        self.fields['switch'].queryset = Book.objects.filter(owner = u)


views.py
d = DropDownList('anthony')

When I try to syncdb I get: "NameError: name 'u' is not defined I have tried to filter using other methods like get(Q(owner = u)) to no avail. I am following the info from this snippet http://djangosnippets.org/snippets/2481/ The dropdownlist was correctly shown when I didn't filter the items it contains.

Check your code:

  1. If you override the __init__ method, don't forget to call super(...).__init__ :

     class DropDownList(forms.Form): switch = forms.ModelChoiceField(queryset=Book.objects.none().order_by('name'), widget=forms.Select(attrs={"onChange": 'submit()'}), required=False, initial=0) def __init__(self, u, *args, **kwargs): super(DropDownList, self).__init__(*args, **kwargs) self.fields['switch'].queryset = Book.objects.filter(owner=u) 
  2. Maybe just mistyping in question, but be sure, that you've used max_length arg, and not max_lenght :

     class Book(models.Model): name = models.CharField(max_length=200, default='') owner = models.CharField(max_length=200, default='') def __unicode__(self): return self.name 

If you need a custom filter when the form is used in different view outputs, you can also construct the form normally with no override for init, and then alter the field querysets:

def my_view_function():
   switch_query ... view specific filters ...
   form = DropDownList()
   form.fields['switch'].queryset = switch_query 
   ... rest of view render ...

Alternatively you could change the constructor to pass in a queryset for these elements too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM