我有以下型号:
class PlaceMixin(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
sublocality = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
class Meta:
abstract = True
class Bar(PlaceMixin):
pass
class Restaurant(PlaceMixin):
pass
酒吧和餐厅的save()方法几乎相同:
def save(self, *args, **kwargs):
try:
bar = Bar.objects.get(address=self.address)
except Bar.DoesNotExist:
Do something
super().save(*args, **kwargs)
def save(self, *args, **kwargs):
try:
restaurant = Restaurant.objects.get(address=self.address)
except Restaurant.DoesNotExist:
Do something
super().save(*args, **kwargs)
我想知道是否可以将该方法放在Abstract模型中,并将其传递给两个继承的模型?
def save(self, *args, **kwargs):
try:
temp = self.objects.get(address=self.address)
except self.DoesNotExist:
Do something
super().save(*args, **kwargs)
这样的东西?但是您可以查询抽象模型。我基本上需要检查是否存在执行动作的实例。
您可以像这样在Mixin类中为Restaurant
和Bar
模型创建通用的保存方法:
from django.apps import apps
class CommonMixin(object):
def save(self, *args, **kwargs):
if self.__class__.__name__ == "Resturant":
model = apps.get_model('app_name', 'Bar')
if model.objects.filter(address=self.address).exists():
...
else:
model = apps.get_model('app_name', 'Restaurant')
if model.objects.filter(address=self.address).exists():
...
super(CommonMixin, self).save(*args, **kwargs)
并同时将其导入Restaurant
和Bar
类:
class Restaurant(CommonMixin, PlaceMixin):
...
class Bar(CommonMixin, PlaceMixin):
...
可能更好的方法是对地址信息使用单独的模型。然后,您将不需要新的Mixin来覆盖保存(上面给出的方法感觉像是过度设计)。因此,假设您有一个不同的地址模型,只需在unique=True
处限制重复的条目即可:
class Address(models.Model):
address = models.CharField(max_length=255, unique=True)
class PlaceMixin(models.Model):
address = models.ForeignKey(Address)
...
您可以使用abstract
元数据来实现。如果要在类模型中使用任何变量,则只需使用self.__class__
,如下所示:
class PlaceMixin(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
sublocality = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
class Meta:
abstract = True
def save(self, *args, **kwargs):
try:
self.__class__.objects.get(address=self.address)
except self.__class__.DoesNotExist:
# Do something
else:
super().save(*args, **kwargs)
class Bar(PlaceMixin):
pass
class Restaurant(PlaceMixin):
pass
[Django源代码中有很多类似这样的代码设计,他们的项目中有很多好的实践,因此请尝试一下。例如:a line of code on Django repo