I have this model:
class Aircraft(models.Model):
model = models.CharField(max_length=64, blank=True)
type = models.CharField(max_length=32)
extra = models.CharField(max_length=32, blank=True)
manufacturer = models.CharField(max_length=32)
engine_type = models.IntegerField("Engine Type", choices=ENGINE_TYPE, default=0)
cat_class = models.IntegerField("Category/Class", choices=CAT_CLASSES, default=1)
And I have a "find aircraft" page where the user is presented with a form where they can enter data that will be used to find all aircraft that fits their criteria. For instance the user can enter "boeing" into a textbox and "jet" into the engine_type
box, and it will display all boeing jets in the database. The way I'm doing this now is by this form:
class AircraftSearch(ModelForm):
search = forms.CharField(max_length=100, required=False)
class Meta:
model = Aircraft
fields = ('engine_type', 'cat_class', )
And then a (needlessly complex) view which converts the data from this form into a set of filter()
's which get added to Aircraft.objects.all()
. (Instead of having 4 seperate search fields for each CharField, I have combined them all into one search field.)
This all works, but with one problem. If the user wants to exclude engine type from their search criteria, then they're screwed because "Any" is not a valid choice for the engine type field. I'm going to have to create a new field/widget for engine type and category/class to include "Any", which kind of defeats the purpose of using a model view in the first place
I'm curious. Is there a better way? This seems like a very common task which has to have been tackled by someone else already, but a google search brings up nothing.
Model Forms are forms that are connected directly to models, allowing them to populate the form with data. It allows you to create a form from a pre-existing model. You add an inline class called Meta, which provides information connecting the model to the form. An inline class is a class within another class.
Let's try to use required via Django Web application we created, visit http://localhost:8000/ and try to input the value based on option or validation applied on the Field. Hit submit. Hence Field is accepting the form even without any data in the geeks_field. This makes required=False implemented successfully.
Django Model Form It is a class which is used to create an HTML form by using the Model. It is an efficient way to create a form without writing HTML code. Django automatically does it for us to reduce the application development time.
Functionally, "any" would be achieved by just not including that particular search vector in the filtering.
Generally, ModelForm
s are for creating and editing models; in this case, I'm not sure it's helping you much more than just doing a regular form:
class AircraftSearch(forms.Form):
search = forms.CharField(max_length=100, required=False)
engine_type = forms.ChoiceField(choices=ENGINE_TYPE)
cat_class = forms.ChoiceField(choices=CAT_CLASS)
To do the search, you then just filter when fields are non-empty:
def search(request):
if request.method == 'POST':
results = Aircraft.objects.all()
search = request.POST.get('search', None)
if search:
results = results.filter(Q(model=search)|Q(type=search)|Q(extra=search)|Q(manufacturer=search))
engine_type = request.POST.get('engine_type', None)
if engine_type:
results = results.filter(engine_type=engine_type)
cat_class = request.POST.get('cat_class', None)
if cat_class:
results = results.filter(cat_class=cat_class)
return render_to_response('aircraft.html', {'form': AircraftSearch(request.POST), 'aircraft': results})
return render_to_response('aircraft.html', {'form': AircraftSearch()})
I think you should not use a ModelForm.
Typical ModelForm usescase is data manipulation, and not its search.
Instead, make a completely new form, based on the fields you need and with checkboxes that user will (de-)select to disable searching a particular field.
Of course, you still should use the choices defined in the model, by simply importing the file and using that list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With