Вопрос по models, django, django-models, field, python – Джанго пустое поле запасной

4

У меня есть модель, которая содержит адрес пользователя. Эта модель должна иметь поля first_name и last_name, так как вы хотите задать адрес получателю (например, его компании и т. Д.). Что я'Я пытаюсь достичь это:

если поле fist_name / last_name в адресе заполнено - просто вернуть это полеесли поле fist_name / last_name в адресе пустое - извлеките соответствующие данные поля из внешнего ключа, указывающего на правильный django.auth.models.UserI 'хотелось бы, чтобы это рассматривалось как обычное поле django, которое будет присутствовать в полях поискаЯ нене хочу создавать метод, так как онs рефакторинг и Address.first_name / last_name используются в разных местах приложения (также в модельных формах и т. д.), поэтому мне это нужно как можно более плавно, иначе япридется повозиться во многих местах

Спасибо за помощь :)

Ваш Ответ

2   ответа
6

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

class MyModel(models.Model):
    _first_name = models.CharField(max_length=100, db_column='first_name')

    @property
    def first_name(self):
        return self._first_name or self.user.first_name

    @first_name.setter
    def first_name(self, value):
       self._first_name = value

Это всегда будет относиться к последнему значению first_name, даже если связанный пользователь был изменен. Вы можете получить / установить свойство точно так же, как и атрибут:myinstance.first_name = 'daniel'

Другой вариант - переопределить модельsave() метод, чтобы он выполнял поиск при сохранении:

def save(self, *args, **kwargs):
    if not self.first_name:
        self.first_name = self.user.first_name
    # now call the default save() method
    super(MyModel, self).save(*args, **kwargs)

Таким образом, вы невам не нужно менять вашу базу данных, но она обновляется только при сохранении - так что если связанный объект User был изменен, но этот объект не 'т, это будет ссылаться на старое значение пользователя.

Есть еще одна крошечная проблема - при поиске django orm может 'Для разрешения поля информации о свойствах требуется исходное поле _first_name. pielgrzym
обновили код и пояснения в ответ на piquadrat 'комментарий. Daniel Roseman
Вы можете указать db_column = 'имя' чтобы предотвратить изменение схемы:docs.djangoproject.com/en/dev/ref/models/fields/#db-column Benjamin Wohlwend
Спасибо за помощь :) это работает безупречно (метод свойства), единственное, что я 'Я обеспокоен - яу нас есть модель формы, и она неЗаполните пустые поля с именем self.user.first_name. Установка атрибута и получение работает без нареканий. pielgrzym
поэтому после @ first_name.setter вещь просто добавьте first_name.db_column = "имя" ? Смогу ли я сделать: address = Address.objects.get (first_name = "бла»)? pielgrzym
0

В некоторых случаях, когда в фильтрах наборов запросов (на уровне базы данных) необходим запасной вариант, можно использовать DjangoCoalesce() учебный класс (документы).

Самым простым решением в таком случае может быть аннотация набора запросов (на примере @ daniel-roseman'sответ):

queryset = MyModel.objects.annotate(first_name=Coalesce('_first_name', 'user__first_name'))

Каждый элемент, полученный из набора запросов, получитfirst_name атрибут, который имеет значение_first_name с запасным вариантом (в случае, если значениеnull) к.user.first_name

То есть, если ваша модель имеетuser связь.

Это может быть реализовано, например, в пользовательском менеджере, а также может быть использован в сочетании сproperty подход.

Подробный пример для подобного случая (переопределение вместо запасного) приведен вэто так ответ.

Похожие вопросы