25👍
Overriding __init__
might work, but it’s bad idea and it’s not the Django way.
The proper way of doing it in Django is using signals.
The ones that are of interest to you in this case are pre_init
and post_init
.
django.db.models.signals.pre_init
Whenever you instantiate a Django
model, this signal is sent at the beginning of the model’s__init__()
method.
django.db.models.signals.post_init
Like
pre_init
, but this one is sent
when the__init__()
: method finishes
So your code should be something like
from django.db import models
from django.db.models.signals import post_init
class MyModel(models.Model):
# normal model definition...
def extraInitForMyModel(**kwargs):
instance = kwargs.get('instance')
do_whatever_you_need_with(instance)
post_init.connect(extraInitForMyModel, MyModel)
You can as well connect signals to Django’s predefined models.
7👍
While I agree that there often is a better approach than overriding the __init__
for what you want to do, it is possible and there might be cases where it could be useful.
Here is an example on how to correctly override the __init__
method of a model without interfering with Django’s internal logic:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# add your own logic
- [Django]-How do you detect a new instance of the model in Django's model.save()
- [Django]-Django AutoField with primary_key vs default pk
- [Django]-Django: how to do calculation inside the template html page?
5👍
The two suggested methods in the docs rely on the instance being created in an arbitrary way:
-
Add a classmethod on the model class:
from django.db import models class Book(models.Model): title = models.CharField(max_length=100) @classmethod def create(cls, title): book = cls(title=title) # do something with the book return book book = Book.create("Pride and Prejudice")
-
Add a method on a custom manager:
class BookManager(models.Manager): def create_book(self, title): book = self.create(title=title) # do something with the book return book class Book(models.Model): title = models.CharField(max_length=100) objects = BookManager() book = Book.objects.create_book("Pride and Prejudice")
If that is your case, I would go that way. If not, I would stick to @vartec’s answer.
- [Django]-Django render_to_string missing information
- [Django]-Add a custom button to a Django application's admin page
- [Django]-Row level permissions in django