Hi,
I'm having trouble using the unique together constraint with a a field which may be None. Given this model:
class Rule(models.Model):
internal = models.BooleanField(default=False)
port_range_from = models.PositiveIntegerField(null=True, blank=True)
port_range_to = models.PositiveIntegerField(null=True, blank=True)
# either cidr_ip or src_group for ingress rules
cidr_ip = IPNetworkField(blank=True, null=True)
is_ingress = models.BooleanField(default=True)
# a security group is used as src in this rule
src_security_group = models.ForeignKey(
SecurityGroup, to_field='uuid', null=True, blank=True)
class Meta:
app_label = "nomos"
unique_together = (
('port_range_from', 'port_range_to', 'cidr_ip', 'src_security_group', 'is_ingress'),
)
Now in this instance src_security_group may be None OR cidr_ip may be None. In this case they are mutually exclusive. Regardless I want to use the unique_together to ensure that no two identical rules are created. However, in the django models/base.py code the following logic is in _perform_unique_check:
lookup_kwargs = {}
for field_name in unique_check:
f = self._meta.get_field(field_name)
lookup_value = getattr(self, f.attname)
if lookup_value is None:
# no value, skip the lookup
continue
if f.primary_key and not self._state.adding:
# no need to check for unique primary key when editing
continue
lookup_kwargs[str(field_name)] = lookup_value
# some fields were skipped, no reason to do the check
if len(unique_check) != len(lookup_kwargs):
continue
Because the lookup_value of a null field is None, the validation check is aborted entirely. This seems wrong to me, and I'm wondering if I'm doing something wrong here. Redefining the models is not something I can do at this point.
Berndt