开发者

Best practices for dependent fields in a django model

开发者 https://www.devze.com 2023-04-07 00:53 出处:网络
For database indexing purposes, the email field on a model needs to be stored in reverse.I end up needing access to both the reversed and forward version of the email field.I\'m curious as to which of

For database indexing purposes, the email field on a model needs to be stored in reverse. I end up needing access to both the reversed and forward version of the email field. I'm curious as to which of the following methods would be considered best practice.

Method A Override the save method on the model. This method denormalizes the database some and doesn't work with the update method on a queryset. Some need to override forms generated for the model.

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) 

Method B This way has better database normalization. Still allows you to use the update method on querysets. Screws up forms so that you end up having to override all of the default forms generated for the model.

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

  @property
  def email_forward(self):
    if not hasattr(self, 'email_f开发者_JS百科'):
      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

Clarification

Any alternative answers need to meet the minimum requirement of having the reversed email stored in the database. This question is however, not so much about finding an answer to this specific problem, but getting feedback on best practices for this sort of scenario where you have two fields which can be computed from one another, but one is required in a frontend context, and the other in a backend context


The Model:

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)

And the Form:

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

Not sure what you meant by "Screws up the form", but this model form will only have one field - the email. I have also added an example of how the models are used:

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') 
0

精彩评论

暂无评论...
验证码 换一张
取 消