Some findings in Django
How to use settings and introspects Django database models.
Recently, I was asked as an exercise for a job interview to create a Django package that introspects a project at its startup time and generates a file with all the database models encountered. The final result can be found here. I will share what I learned from this project.
Note: The following content will only be useful for you if you already have the basics in Django. If it is not the case, I encourage you to read their excellent tutorial.
How to effectively access project settings.
A naive way to think about how to retrieve the project settings is to access directly the settings
module found in the project. But this is a bad idea because not all settings used by Django are found in that module. Some of them are defined in django.conf.global_settings
. The correct way to access Django settings is like the following:
from django.conf import settings
if settings.DEBUG:
# Do something
Don’t try this:
from django.conf.settings import DEBUG
The previous code will not work because settings
here is an object and not a module.
Also, don’t try to alternate settings at runtime, you may experience unexpected behaviors.
from django.conf import settings
settings.DEBUG = True # Don't do this!
The only way to assign to settings is in the settings file.
Instropect a Django Model
I was asked to inspect models and retrieve the field names and types. I found that each Django model has a_meta
attribute (which is an instance of the django.db.models.Option
class) I can use for my goal. It has a method get_fields
that I can use like the following:
# model here is a django db.Model class like User, Comment,...
for field in model._meta.get_fields():
yield field.name, field.__class__.__name__
Get all concrete models in a models module
Another thing to take into account is that I don’t want to include abstract or proxy models in the resulting file because these models don’t have a representation in a database. Again all this information can be found in the _meta
attribute. So the logic to get all concrete models in the project is as follows:
# we assume we have a function to iterate all models
for model in get_models():
if not model._meta.abstract and not model._meta.proxy:
for field in model._meta.get_fields():
yield field.name, field.__class__.__name__
Do something when a Django project starts running
Another requirement was to scan the project for models when it starts running. Normally all Django applications have an apps
module with a class that inherits from django.apps.AppConfig
. This class has an empty ready
function that is intended to be overridden to execute code at project startup.
from django.apps import AppConfig
class ScanormConfig(AppConfig):
name = 'scanorm'
def ready(self):
# All you write here will be executed when the project starts running
create_model_schema()
This is all for this article. Hope you enjoyed it. Take care of yourself and see you next time! 😁
If you like my article and want to continue learning with me, don’t hesitate to follow me here and subscribe to my newsletter on substack 😉