Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialandetin
5,263 PointsHow to filter ModelChoiceField by fields?
I have a Car model that contains several data:
class Car(models.Model):
make = models.CharField(max_length=50)
model = models.CharField(max_length=50)
platform = models.CharField(max_length=50)
(...)
For instance: [make="BMW", model="5 Series", platform="E39"]
My forms.py:
from django import forms
from .models import Car
class CarForm(forms.ModelForm):
make = forms.ModelChoiceField(queryset=Car.objects.values_list('make',flat=True).distinct())
model = forms.ModelChoiceField(queryset=Car.objects.values_list('model',flat=True).filter(make=make).distinct())
plaform = forms.ModelChoiceField(queryset=Car.objects.values_list('platform',flat=True).filter(make=make, model=model).distinct())
class Meta:
model = Car
fields = ["make", "model", "platform"]
My views.py:
from django.shortcuts import render
from django.views.generic import View
from .models import Car
from .forms import CarForm
class CarFormView(View):
form_class = CarForm
template_name = "reviews/car.html"
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {"form": form})
I want to filter all the instances of Car model by 3 consecutive ModelChoiceField's:
- 1st one only shows distinct makes (done),
- 2nd one only shows models with make=first step's choice,
- 3rd one only shows platform with make=first step's choice & model=second step's choice.
How do I make such a dependent filter in my forms? Without jQuery, if possible.
Thank you!
2 Answers
Chris Freeman
Treehouse Moderator 68,441 PointsThe question to ask is "How does the form know to change the second and third choice list based on the results of the first choice?" You obviously can not pre-populate the second and third choices until the first choice has been made.
Two main paths for this:
- POST the form when the first answer is chosen, then based on the post info, redisplay the form with the first choice set and the second selection updated based on the first choice. Repeat to update the third choice selections after second choice has been made. This will make the view more complicated because it will have to decide which stage the form in: first, second, or third choice selection.
- Use a jQuery/javascript/ajax call to dynamically get the updated choices from the server.
Sorry there isn't a simple cookie cutter solution for this. Hints may be found in these examples: this one or this one or Django extensions like django-autocomplete-light or django-smart-selects
Disclaimer: I haven't validated any of the suggested hints (you mileage may vary!) Good Luck!!
Chris Freeman
Treehouse Moderator 68,441 PointsOld post, but if you haven't solved it, have you tried:
<form action="{% url 'reviews:model-select' make=make %}" method="POST">
When passing parameters to a URL you need to include the keyword
andetin
5,263 Pointsandetin
5,263 PointsThank you for your reply. I tried Django Autocomplete Light but couldn't make the "forward" widget work. And Django Smart Select only works with chained foreignkeys, but I've got single model.
So I'm following first solution. I couldn't figure out how to filter make, model and plaform on the same page with one view. My forms.py:
Views.py:
Makeselect.html:
URL's:
I'm getting this error:
So... I can not pass "make" argument to my model-select URL. Also, should I edit my ModelSelectForm so that it initiliazes with make=first step's selection?