S.D.
S.D.

Reputation: 2951

Django create() not applying annotations applied on manager

Imagine the following model, manager and queryset:

from django.db import models

class BlaQuerySet(models.QuerySet):
    def annotate_field(self):
        return self.annotate(bla_field=Value('Bla')

class BlaManager(models.Manager):
    def get_queryset(self):
        return BlaQuerySet(self.model, using=self._db).annotate_field()

class Bla(models.Model):
    hello = models.CharField(max_length=10)
    objects = BlaManager()

Now that we have the model. Let's create something:

bla_instance = Bla.objects.create(hello='something')
bla_instance.bla_field

returns

`AttributeError: 'Bla' object has no attribute 'bla_field'

On the other hand, when you filter that item:

bla_instance = Bla.objects.get(hello='something')
bla_instance.bla_field

returns the expected Bla

Using the setting: Meta.base_manager_name = 'objects' does not help.

How can I force the create() to use my manager instead of the default one?

Upvotes: 0

Views: 31

Answers (1)

itismoej
itismoej

Reputation: 1847

You can override create method of the QuerySet:

class BlaQuerySet(models.QuerySet):
    def annotate_field(self):
        return self.annotate(bla_field=models.Value('Bla'))

    def create(self, **kwargs):
        obj = super().create(**kwargs)
        return self.get(pk=obj.pk)

Note: Be aware that this makes another query to the database.

But I suggest you to use a property in this case:

class Bla(models.Model):
    hello = models.CharField(max_length=10)

    @property
    def bla_field(self):
        return 'Bla'

Upvotes: 0

Related Questions