Write better Django views

Posted on Fri 12 March 2021 in Better Django


Should you use class-based views (CBV's) or function-based views (FBV's) in Django? It seems a lot of people are pushing CBV's, touting them to be the "standard" way of writing views in Django. But why do FBV's still exist then? Just for backward-compatibility? This is my highly opinionated "view" (see what I did there??) on this matter.

The topic is hotly debated. Why are some people so passionate about CBV's? CBVs are said to be better because they abstract a lot of boiler-plate code into base classes and mixins. This is true. As a very basic example, instead of writing …

Continue reading

Learn the subtle differences between Save and Update in Django

Posted on Fri 12 February 2021 in Better Django

To save data in Django, you normally use .save() on a model instance. However the ORM also provides a .update() method on queryset objects. So which one should you use? Let's take a look at each, and then decide which one to use in which situations.


The .save() method is used to write a model instance to the database. It can be an existing record or even a new one. For an existing record, Django will run a SQL UPDATE statement on the database. For a new record, Django will run an INSERT. Before Django 3.0, it would …

Continue reading

Results - VS Code vs PyCharm

Posted on Tue 02 February 2021 in Misc

I asked Reddit about text editors vs IDEs. In particular, I asked VS Code users why they preferred it over IDEs like PyCharm, and then I asked PyCharm users why they preferred it over text editors like VS Code. The results were very interesting.

VSCode users: Why do you prefer it over PyCharm?

PyCharm users: Why do you prefer it over VSCode or other editors?

Results: VS Code

Among VS Code users, the following reasons were listed most:


Results: PyCharm

And among PyCharm users, the following reasons were most common:



Looking at the above, I can conclude a few …

Continue reading

Speed up bulk-exists check with python sets

Posted on Sat 01 August 2020 in Better Django


The .exists() function of Django's ORM is very useful. However, if you need to do this in bulk (think hundreds of thousands or more), this becomes a strain on your database. Let's say you are fetching records from an external system, and if the record doesn't exist locally, you need to do something:

for item in external_records:
    if not Data.objects.filter(external_id=item.id).exists():
        # Do something

If you are working with a large quantity of records, this will flood your DB with queries. Instead, you could first pull all external_id values from the DB:

existing_ids = Data.objects.all …

Continue reading

Early Exit

Posted on Sun 12 July 2020 in Better Python


You will have definitely come across the following pattern often:

if post_data:
    thing = post_data.get("thing")
    if thing is not None:
        setting = get_user_setting(user, thing)
        if setting is not None:
            permission = get_user_permission(user)
            if permission is True:
                if user.is_superuser:
                    return DataPoint.objects.all()
                elif user.is_staff:
                    return DataPoint.objects.filter(user=user)
                    return DataPoint.objects.filter(user=user, thing=thing)
                return "Permission denied"
            return "Setting not found"
        return "Thing not specified"
    return "No data posted"

What is good about the code above? It follows the thought process that most developers would have: which conditions …

Continue reading