Лучшие практики для зависимых полей в модели Django - PullRequest
0 голосов
/ 23 сентября 2011

В целях индексации базы данных поле электронной почты на модели необходимо хранить в обратном порядке. В итоге мне понадобился доступ как к обратной, так и к переадресованной версии поля электронной почты. Мне любопытно, какой из следующих методов будет считаться наилучшей практикой.

Метод А Переопределите метод save на модели. Этот метод немного денормализует базу данных и не работает с методом update в наборе запросов. Некоторые должны переопределить формы, сгенерированные для модели.

class Foo(models.Model):
  email_forward = models.CharField(max_length = 320)
  email_reversed = models.CharField(max_length = 320)

  def save(self, *args, **kwargs):
    self.email_reversed = reversed(self.email_forward)
    super(Foo, self).save(*args, **kwargs) 

Метод B Этот способ имеет лучшую нормализацию базы данных. Тем не менее позволяет использовать метод update для наборов запросов. Разбивает формы, так что в итоге вам придется переопределить все формы по умолчанию, сгенерированные для модели.

class Foo(models.Model):
  _email = models.CharField(max_length = 320)

  @property
  def email_forward(self):
    if not hasattr(self, 'email_f'):
      self.email_f = reversed(self._email)
    return self.email_f

  @email.setter
  def email_forward(self, value):
    self.email_f = value
    self._email = reversed(value)

  @propery
  def email_reversed(self):
    return self._email

Разъяснение

Любые альтернативные ответы должны соответствовать минимальному требованию хранения обратной электронной почты в базе данных. Этот вопрос, однако, заключается не столько в поиске ответа на эту конкретную проблему, сколько в получении отзывов о передовых практиках для такого сценария, когда у вас есть два поля, которые можно вычислить друг из друга, но одно требуется в контексте внешнего интерфейса, а другой в контексте бэкэнда

1 Ответ

1 голос
/ 23 сентября 2011

Модель:

class Foo(models.Model):
    email = models.CharField(max_length=320)

    def _get_email_reversed(self):
        return self.email[::-1]

    def _set_email_reversed(self, value):
        self.email = value[::-1]

    email_reversed=property(_get_email_reversed, _set_email_reversed)

И Форма:

class FooForm(forms.ModelForm):    
    class Meta:
        model = Foo

Не уверен, что вы имели в виду под «Пьяной формой», но эта модель будет иметь только одно поле - email. Я также добавил пример того, как используются модели:

def test_foo(self):
    foo = Foo()
    foo.email = 'moc.elpmaxe@liametset'
    self.assertEquals(foo.email_reversed, 'testemail@example.com')

def test_set_foo_reversed(self):
    foo = Foo()
    foo.email_reversed = 'testemail@example.com'
    self.assertEquals(foo.email, 'moc.elpmaxe@liametset') 
...