Django 检查两个字段之间的唯一字段条目

Django checking unique Field Entries between two fields

我有一个问题,我必须从管理页面为给定用户存储两个 IP 字段。 我的用户模型定义如下:

class userIPs(models.Model):
   IP_Address_1 = models.GenericIPAddressField(blank=False)
   IP_Address_2 = models.GenericIPAddressField(blank=False)
   class Meta:
     unique_together = (('IP_Address_1', 'IP_Address_2',),)

IP_Address_1 = models.GenericIPAddressField(blank=False, unique = True)
IP_Address_2 = models.GenericIPAddressField(blank=False, unique = True)

使用任一实现,我只能检查一个特定 IP 字段的唯一性。

例如:如果 user1 具有以下值,

IP_Address_1 = 10.0.0.1; IP_Address_2 = 10.0.0.2

如果我尝试添加相同的值,系统会按预期引发异常。 但是,当我尝试添加其他用户值时,例如

IP_Address_1 = 10.0.0.2; IP_Address_2 = 10.0.0.1

添加值时没有进行任何唯一性检查。

我想通过检查 IP_Address_1 和 IP_Address_2 来确保 IP 是唯一的。 有没有办法检查多个字段的唯一性?

谢谢!

Is there a way to check multiple fields for uniqueness?

您可以更新模型的 save 方法来检查两个 IP 是否唯一。

类似的东西:

def save(self, *args, **kwargs):
    if not (userIPs.objects.filter(IP_Address_1=self.IP_Address_1).exists() and userIPs.objects.filter(IP_Address_2=self.IP_Address_2).exists())
        super(Model, self).save(*args, **kwargs)
    else:
        print "IP not unique"

除非两个 IP 地址中的 "order" 很重要,否则只需将它们排序在您的 save() 中,其余的请相信您的数据库。

def save(self, *args, **kwargs):
    self.ip1, self.ip2 = sorted((self.ip1, self.ip2))
    return super(UserIps, self).save(*args, **kwargs)

编辑:

对于要求

I want the IP address to be unique for all the users. i.e., If user1 has IP1, IP2, then user 2 must have IP3, IP4 and so on

最好重构一下:

class IpAddress(models.Model):
    user = models.ForeignKey(User)
    ip = models.GenericIpAddressField(unique=True)

并确保您永远不会超过两个(或任何您的业务需求)IpAddresses per user.

请注意:我是提出问题的人。认为答案可能对某人有用。

要验证两个不同字段中的值,我们可以使用:

  1. unique=True同一领域的唯一性

  1. def clean(self, *args, **kwargs): 验证其他字段的函数。

所以,我的最终模型如下

class userIPs(models.Model):
   IP_Address_1 = models.GenericIPAddressField(blank=False, unique = True)
   IP_Address_2 = models.GenericIPAddressField(blank=False, unique = True)

   def clean(self, *args, **kwargs):
       if (userIPs.objects.filter(IP_Address_2=self.IP_Address_1).exists()):
           raise ValidationError('IP Address 1 value already exists.')
       elif (userIPs.objects.filter(IP_Address_1=self.IP_Address_2).exists()):
           raise ValidationError('IP Address 2 value already exists.')
       else:
           super(userIPs, self).clean(*args, **kwargs)
   
   def __unicode__(self):
       return self.user.username