Почему использование filter () дает то, что я хочу, но с get () вызывает ошибку

#python #django #model #django-queryset #attributeerror

#python #django #Модель #django-набор запросов #attributeerror

Вопрос:

Я создал набор запросов cusom и Manager для сериализации моих данных.

 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()
  

Затем, когда я пытаюсь получить эти данные, это сработало с этим:

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

но вызывает AttributeError (объект ‘Update’ не имеет атрибута ‘serialize’) с этим:

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

Комментарии:

1. Потому что .filter возвращает a, queryset в то время как get возвращает object ?

2. .serialize является функцией для UpdateQuerySet объекта, .filter() возвращает такое QuerySet , тогда как .get() это всего лишь простой объект.

Ответ №1:

Вы также хотите добавить serialize к UpdateManager

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

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

Ответ №2:

Ваш Update.objects.filter(id=1) возвращает UpdateQueryset , и это QuerySet предлагает .serialize(…) метод. .get(id=1) Функция вернет объект Update модели , а не QuerySet , а модель по умолчанию не предлагает .serialize(…) метод.

Однако вы можете реализовать это самостоятельно и даже обобщить QuerySet для работы со всеми видами моделей, такими как:

 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)  

Итак, теперь все модели, которые наследуются от SerializableModel , как Update , например, now, будут использовать SerializableManager и, более того, унаследуют .serialize() метод, с которым вы также можете работать, Update.objects.get(pk=1).serialize() например.