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)