Create or Update with a Django ModelForm

I recently had a use case where I needed to have a single form that could act as either a create or update form. The tricky part was that I wouldn’t know which one was necessary until the data was submitted by the user.

To solve this, I started with Django’s generic UpdateView and overwrote the get_object method so that it would either get the existing record or create a new one (using get_or_create) based on the data being submitted. In my case (and the example below), I had two values that determined whether a new record was necessary or if an existing one should be used.

The underlying ModelForm didn’t require any modification (you could even just use Django’s automatically generated ModelForm by specifying the model in your view).

Here’s the code:

Sort Django Query (Order By) Using Values Within IN()

In MySQL, you can use the FIELD() function to easily sort a result set by a list of ordered ids:

To accomplish this in Django, you can make use of the extra() QuerySet method to create an additional field in the SELECT statement which can then be using for sorting in the FIELD method.

Combine 2 Django Querysets from Different Models

If you’ve ever tried to concatenating two or more querysets from different models (i.e. combined = queryset1 | queryset2), you’ve hit this lovely error:

Cannot combine queries on two different base models.

The solution to this is to use itertools.

This allows you to not only combine the querysets into a single iterable, but it also allows you to sort the entire set by a shared field such as the date created: