Artem Soryn
Artem Soryn

Reputation: 45

Why using filter() gives what I want, but with get() raises an error

I created cusom QuerySet and Manager to serialize my data.

class UpdateQuerySet(models.QuerySet):
    def serialize(self):
        return serialize("json", self)

class UpdateManager(models.Manager):
    def get_queryset(self):
        return UpdateQuerySet(self.model, using=self._db)

class Update(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    objects = UpdateManager()

Then, when I'am trying to get this data, it worked with this:

json_data = Update.objects.filter(id=1).serialize()

but raises AttributeError ('Update' object has no attribute 'serialize') with this:

json_data = Update.objects.get(id=1).serialize()

Upvotes: 1

Views: 64

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476534

Your Update.objects.filter(id=1) returns an UpdateQueryset, and that QuerySet offers a .serialize(…) method. The .get(id=1) function will return an Update model object, so not a QuerySet, and a model by default does not offer a .serialize(…) method.

You can however implement this yourself, and even generalize the QuerySet to work with all sorts of models, like:

class SerializableQuerySet(models.QuerySet):
    def serialize(self):
        return serialize('json', self)

class SerializableManager(models.Manager):
    _queryset_class = SerializableQuerySet

    def serialize(self, *args, **kwargs):
        return self.get_queryset().serialize(*args, **kwargs)

class SerializableModel(models.Model):
    objects = SerializableManager()
    
    def serialize(self):
        return serialize('json', [self])

    class Meta:
        abstract = True

class Update(SerializableModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

So now all models that inherit from SerializableModel, like Update for example now will use a SerializableManager, and furthermore will inherit a .serialize() method, such that you can also work with Update.objects.get(pk=1).serialize() for example.

Upvotes: 0

S.D.
S.D.

Reputation: 2941

You also want to add serialize to the UpdateManager

class UpdateManager(models.Manager):
    def get_queryset(self):
        return UpdateQuerySet(self.model, using=self._db)

    def serialize(self):
        return self.get_queryset().serialize()

Upvotes: 1

Related Questions