【问题标题】:Django checking unique Field Entries between two fieldsDjango 检查两个字段之间的唯一字段条目
【发布时间】:2015-07-05 17:51:07
【问题描述】:

我有一个问题,我必须从管理页面为给定用户存储两个 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 是唯一的。 有没有办法检查多个字段的唯一性?

谢谢!

【问题讨论】:

  • 您要检查(IP1 和 IP2)是否是唯一的,还是任何地址都必须是唯一的?换句话说:如果用户 1 拥有 IP1 和 IP2,那么拥有 IP1 和 IP3 的用户 2 应该通过吗?
  • 我希望所有用户的 IP 地址都是唯一的。即,如果用户1有IP1、IP2,那么用户2必须有IP3、IP4等等
  • 然后将模型重构为每个模型(行)只有一个 IP 地址,使其唯一,并确保在其他地方单个用户拥有的实例不超过 2 个。

标签: python django python-2.7 django-models


【解决方案1】:

有没有办法检查多个字段的唯一性?

您可以为您的模型更新 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"

【讨论】:

  • 这个实现和我当前的 unique=True 完全一样,出于某种原因,它只分别检查 IP_address_1、IP_address_2 字段,而不检查其他字段中的值。
【解决方案2】:

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

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

  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
    

【讨论】:

    【解决方案3】:

    除非两个 IP 地址的“顺序”很重要,否则只需在您的 save() 中对它们进行排序,其余的则信任您的数据库。

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

    编辑:

    根据需求

    我希望所有用户的 IP 地址都是唯一的。即,如果用户1有IP1、IP2,那么用户2必须有IP3、IP4等等

    最好重构:

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

    并确保每个userIpAddresses 永远不会超过两个(或任何您的业务要求)。

    【讨论】:

    • 嗨@AKX,感谢您的回答,我当前的 IpAddress 类与此类似,但有两个 IP 字段,您所说的重构究竟是什么意思?我是 Django 的新手
    猜你喜欢
    • 2013-10-08
    • 2017-10-30
    • 1970-01-01
    • 2016-07-10
    • 2010-11-13
    • 2014-02-02
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多