如何在抽象模型中创建保存方法来检查实例是否存在?

问题描述 投票:0回答:2

我有以下型号:

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)

这样的东西?但是您可以查询抽象模型。我基本上需要检查是否存在执行动作的实例。

django django-models django-queryset
2个回答
0
投票

您可以像这样在Mixin类中为RestaurantBar模型创建通用的保存方法:

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)

并同时将其导入RestaurantBar类:

 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)
     ...

0
投票

您可以使用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

© www.soinside.com 2019 - 2024. All rights reserved.