I see in the Django documentation :
Model Instance reference : Creating objects
You may be tempted to customize the model by overriding the
__init__
method. If you do so, however, take care not to change the calling signature as any change may prevent the model instance from being saved.
Rather than overriding__init__
, try using one of these approaches:
- Add a classmethod on the model class.
- Add a method on a custom manager (usually preferred)
Why is the second solution "usually preferred" ?
In a situation where I have a model B
which extends a model A
through a OneToOne
relation, and I want to create a method generating a B
object which generates the corresponding A
object as well, how is it "better" to use a custom manager as suggested, given I'll probably not use this manager for anything other than what is provided by default manager ?
I think it is preferred because it looks cleaner in code. You might also be reading into the emphasizes a bit too much, as the benefit or difference isn't that big. That said, when implementing things myself I do use the proposed approach.
Consider the following model (purely for illustrative purposes):
class Vehicle(models.Model):
wheels = models.IntegerField()
color = models.CharField(max_length=100)
In your application, the need often arises to get all cars, or all motorcycles, or whatever type of vehicle. To keep things DRY, you want some standard form of retrieving this data. By using class methods, you'd get the following:
class Vehicle(models.Model):
#(...)
@classmethod
def cars(cls):
return Vehicle.objects.filter(wheels=4)
cars = Vehicle.cars()
green_cars = Vehicle.cars().filter(color='green')
If you create a manager, you'll get something like this:
class CarManager(models.Manager):
def get_query_set(self):
return super(CarManager, self).get_query_set().filter(wheels=4)
class Vehicle(models.Model):
#(...)
car_objects = CarManager()
cars = Vehicle.car_objects.all()
green_cars = Vehicle.car_objects.filter(color='green')
In my opinion, the latter looks cleaner, especially when things get more complex. It keeps the clutter out of your model definitions, and keeps things similar to using the default objects
manager.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With