Django Custom Manager добавить атрибут

У меня есть модель Django, которая выглядит так:

class MyModel(models.Model):
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    nonDbField = SomeObject()
    objects = MyCustomManager()

field1 на самом деле является PK для абстрактного класса SomeObject.

Мне нужен собственный менеджер, который для каждого значения, возвращаемого любой из функций (all, filter, get и т. Д.), Выполняет следующие действия:

 value.nonDbField = SomeObject.objects.get(pk=value.field1)

Я проверил, что я могу вручную переопределить получить вот так:

class MyCustomManager(models.Manager):
    def get(self, *args, **kwargs):
        value = super(MyCustomManager, self).get(*args, **kwargs)
        value.nonDbField = SomeObject.objects.get(listid=value.itemListID)
        return value

но задавался вопросом, есть ли более легкий способ сделать это через все функции.

Многие из вас скажут: "Зачем ты это делаешь?". Это связано с модельным наследованием устаревшей, но все еще активной базы данных.

1 ответ

Решение

Если вам нужно, чтобы значение nonDbField было связано с field1 (или любым другим полем в модели), вы можете попробовать что-то вроде этого:

Class MyModel(models.Model):

    # your fields here...

    def _nonDbField(self):
        return SomeObject.objects.get(pk=self.field1)
    nonDbField = property(_nonDbField)

Это позволяет вам сделать что-то вроде этого:

MyModel.objects.get(pk=1).nonDbField

Имейте в виду, что вы делаете запрос к базе данных каждый раз, когда вы получаете доступ nonDbField (что может отрицательно сказаться на производительности вашей БД).

Вы можете использовать property для ваших вычисляемых полей

Класс MyModel(models.Model):

# your fields here...
first_name = models.CharField()
last_name = models.CharField()

@property
def fullname(self):
    return f"{self.first_name} {self.last_name}"

Это позволяет сделать что-то вроде этого:

obj = MyModel.objects.get(pk=1)
print(obj.fullname)
Другие вопросы по тегам