拥有多个地址的客户只能有一个主地址



我在Django安装中创建了一个应用程序"customerbin"。我需要创建/编辑/删除可以有多个地址的客户,其中只有一个地址可以是主要地址。如果一个客户被删除,那么属于该客户的所有地址也需要被删除。如果创建了新客户,我们就无法从其他客户那里挑选地址。

型号.py:

from django.db import models
class Address(models.Model):
street = models.CharField(max_length=100)
number = models.IntegerField(null=True)
postal = models.IntegerField(null=True)
city = models.CharField(max_length=100)
country = models.CharField(max_length=100)
is_primary = models.BooleanField(null=False)
geo_lat = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
geo_lon = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
class Customer(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
vat = models.CharField(max_length=100)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
address = models.ForeignKey(Address, on_delete=models.CASCADE)

admin.py:

from django.contrib import admin
from . import models
# Register your models here.
admin.site.register(models.Customer)
admin.site.register(models.Address)

我如何才能做到:

  • 一个地址只链接到一个客户
  • 删除客户时删除所有地址
  • 只有一个地址是客户的主要地址

您应该有一个从AddressCustomer的外键,而不是从CustomerAddress的外键。为了确保用户只存在一个主地址,请使用带有condition:的UniqueConstraint[Django-docs]

from django.db.models import Q

class Address(models.Model):
street = models.CharField(max_length=100)
number = models.IntegerField(null=True)
postal = models.IntegerField(null=True)
city = models.CharField(max_length=100)
country = models.CharField(max_length=100)
is_primary = models.BooleanField(null=False)
geo_lat = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
geo_lon = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
# Here ↓
customer = models.ForeignKey("Customer", on_delete=models.CASCADE, related_name="addresses")

def save(self, *args, **kwargs):
if self.is_primary:
self.__class__._default_manager.filter(customer=self.customer, is_primary=True).update(is_primary=False)
super().save(*args, **kwargs)

class Meta:
constraints = [
models.UniqueConstraint(
fields=['customer'],
condition=Q(is_primary=True),
name='unique_primary_per_customer'
)
]

class Customer(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
vat = models.CharField(max_length=100)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)

# Remove address from here

这里,如果相关客户被删除,on_delete=models.CASCADE将导致地址被删除。

首先,您错误地链接了这两个模型。根据上面的代码,当相应的地址被删除时,用户就会被删除,这不是你想要的。所以,这是我的建议。将Address模型中的外键添加到具有on_delete=models.CASCADECustomer模型中,还将具有默认值的Address模型中的布尔字段is_primary添加到False。在Address模型的clean方法中,您可以只处理一个主地址的逻辑,在该方法中,可以检查是否已经有要添加地址的用户的主地址。如果是,则创建一个验证错误。如果没有,请照常进行。如果这个解释还不够,我也可以帮助你编写代码。

相关内容

最新更新