Usage

For these examples we will use the following models:

class MyModel(models.Model):
   age = models.IntegerField()
   employed = models.NullBooleanField()#Yes,No,Unknown
   degree = models.CharField(max_length = 2, choices = [["HS", "High School"],
                                                        ["C", "College"],
                                                        ["G", "Graduate"],
                                                        ["PG", "Post Graduate"]]
                             )

class MyInstitution(models.Model):
   name = models.CharField(max_length=50)
   accredited = models.BooleanField()

   def __str__(self):
      return "%s" % self.name

To use django-modelqueryform in a project import it into forms.py:

import modelqueryform

Then we can use it as a Base class for your forms:

class MyModelQueryForm(modelqueryform.ModelQueryForm):
    model = MyModel
    inclue = ['age','employed','degree']

Thats it! Instantiating MyModelQueryForm gives us a form with 3 widgets

  • Age (RangeField using a RangeWidget)
  • Employed (MultipleChoiceField using a CheckboxSelectMultiple widget)
  • Degree (MultipleChoiceField using a CheckboxSelectMultiple widget)

Once the form is POSTed to the view it is used to filter your model:

query_form = MyModelQueryForm(request.POST)
my_models = query_form.process()

process([data_set=None]) generates a Q object which is a logical AND of the Q objects generated for each widget. It uses the resulting Q object to filter the associated model class.

Note

process() optionally accepts a QuerySet of a model class ‘x’ where isinstance(x, ‘form model class’) is True If no QuerySet is passed, the Q object will run against model.objects.all()

Using pretty_print_query() you get a dict() of the form {str(field.label): str(field values)} to parse into a template:

query_form = MyModelQueryForm(request.POST)
query_parameters = query_form.pretty_print_query()

pretty_print_query() also accepts an argument fields_to_print, a list of names that must be a subset of self.changed_data.

Working with Relations

django-modelqueryform can work with realtionship fields in two different ways, either following the relation or using the relationship field as a choice field.

Let’s add a new field to MyModel from the example above:

class MyModel(models.Model):
   ...
   institution = models.ForeignKey('MyInstitution')

If we want our users to be able to select for (non)-accredited institions we would instantiate the form like so:

class MyModelQueryForm(modelqueryform.ModelQueryForm):
    model = MyModel
    inclue = ['age','employed','degree', 'institution__accredited']
    traverse_fields = ['institution',]

Alternatively we can use the relationship field as a MultipleChoiceField:

class MyModelQueryForm(modelqueryform.ModelQueryForm):
    model = MyModel
    inclue = ['age','employed','degree', 'institution']

Warning

To make the choices for a relationship field, django-modelqueryform does an objects.distinct() call. Be aware of the size of the resulting QuerySet

Defaults

djagno-modelqueryform tries to provide meaningful default where it can. Default widgets, Q objects, and print representation exist for model fields that are stored as numeric values or have choices (either defined or by default, ie. BooleanField(s))

Note

See Customization for how to handle field type that don’t have defaults

Default Fields

Model Field Form Field/Widget Q Object Print Representation
AutoField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
BigIntegerField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
BinaryField      
BooleanField MultipleChoiceField / CheckboxSelectMultiple OR([field=value],...) ‘CHOICE1,CHOICE2,...CHOICEn’
CharField      
CommaSeparatedIntegerField      
DateField      
DateTimeField      
DecimalField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
EmailField      
FileField      
FilePathField      
FloatField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
ImageField      
IntegerField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
IPAddressField      
GenericIPAddressField      
NullBooleanField MultipleChoiceField / CheckboxSelectMultiple OR([field=value],...) ‘CHOICE1,CHOICE2,...CHOICEn’
PositiveIntegerField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
PositiveSmallIntegerField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
SlugField      
SmallIntegerField RangeField / RangeWidget AND([field__gte=min],[field__lte=max]), OR(field__isnull=True) ‘MIN - MAX [(include empty values)]’
TextField      
TimeField      
URLField      
ForeignKey MultipleChoiceField / CheckboxSelectMultiple OR([field=value],...) ‘CHOICE1,CHOICE2,...CHOICEn’
ManyToManyField MultipleChoiceField / CheckboxSelectMultiple OR([field=value],...) ‘CHOICE1,CHOICE2,...CHOICEn’
OneToOneField MultipleChoiceField / CheckboxSelectMultiple OR([field=value],...) ‘CHOICE1,CHOICE2,...CHOICEn’