gpt4 book ai didi

python - 解决 Django 模型不同验证的设计模式

转载 作者:太空宇宙 更新时间:2023-11-04 06:02:20 25 4
gpt4 key购买 nike

我正尝试在 Django 1.6.4 中为我的客户编写应用程序

我对 Django 有丰富的经验,但这个案例对我来说很难解决。

我正在使用 Substituting a custom user model功能和我的 Member 类看起来像(这只是简单的代码片段):

class Member(AbstractBaseUser):
...
date_of_birth = models.DateField()
height = models.FloatField()
...
REQUIRED_FIELDS = ['date_of_birth', 'height']

My Member 可以定义多个不同国家的地址。每个国家都有自己特定的地址验证或额外的字段,所以我定义了主要的抽象地址和一些子地址:

class COUNTRIES(object):
POLAND = 'pl'
GERMANY = 'de'
@classmethod
def to_choices(cls):
return ((cls.POLAND, 'Poland'), (cls.GERMANY, 'Germany'))

class BaseAddress(models.Model):
class Meta:
abstract = True
member = models.ForeignKet(settings.AUTH_USER_MODEL, related_name='+')
country = models.CharField(max_length=2, choices=COUNTRIES.to_choices)

class AddressPL(BaseAddress):
street = models.CharField(max_length=80)
city = models.CharField(max_length=20)
postal_code = models.CharField(max_length=6, validators=[RegexValidator('^\d{2}-\d{3}$'),])
def save(self, *args, **kwargs):
self.country = COUNTRIES.POLAND
super(AddressPL, self).save(*args, **kwargs)

class AddressDE(BaseAddress):
street = models.CharField(max_length=80)
city = models.CharField(max_length=20)
postal_code = models.CharField(max_length=6, validators=[RegexValidator('^\d{5}$'),])
def save(self, *args, **kwargs):
self.country = COUNTRIES.GERMANY
super(AddressPL, self).save(*args, **kwargs)

如您所见,唯一的变化是 validators 部分的 postal_code 字段。唯一的问题是,在 Member 中,我需要添加如下内容:

class Member(AbstractBaseUser):
...
@property
def addresses(self):
from itertools import chain
addresses_pl = AddressPL.objects.filter(member=self)
addresses_de = AddressDE.objects.filter(member=self)
return list(chain(addresses_pl, addresses_de))

基于 431628-how to combine 2 or more querysets

我的问题是。你有什么其他的想法来设计这个吗?我需要提供简单、可扩展的解决方案。也许有使用代理的想法?

最佳答案

我认为concrete inheritance可能是您的问题的候选人:

class Member(AbstractBaseUser):
...
date_of_birth = models.DateField()
height = models.FloatField()
...
REQUIRED_FIELDS = ['date_of_birth', 'height']

class BaseAddress(models.Model):
# no abstract = True
member = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='adresses')
country = models.CharField(max_length=2, choices=COUNTRIES.to_choices)

class AddressPL(BaseAddress):
# your custom logic here

class AddressDE(BaseAddress):
# your custom logic here

然后,如果你想添加一些数据:

m = Member(yourargs)
m.save()

adress1 = AdressPL(yourargs)
adress1.member = m
adress1.save()

adress2 = AdressPL(yourargs)
adress2.member = m
adress2.save()

m = Member.objects.get(pk=m.pk)

m.adresses.all() # will output a list of BaseAdresse instances

这样,添加一种新的地址只是子类化 BaseAdress 的问题。无需更改您的用户模型。

具体继承的缺点是它会在继承模型的数据库查询中添加一个连接。

另外,如果你走这条路,看看django-polymorphic ,它是一个 Django 应用程序,提供了处理具体继承的有用方法。

关于python - 解决 Django 模型不同验证的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24165435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com