I have a Django Model
where I’d like to ensure that no duplicate Edge
exists where the same pair of Node
s appear as node_a
or node_b
, in either order.
class Edge(models.Model):
project = models.ForeignKey(Project, related_name="edges", on_delete=models.CASCADE)
node_a = models.ForeignKey(Node, related_name="+", on_delete=models.CASCADE)
node_b = models.ForeignKey(Node, related_name="+", on_delete=models.CASCADE)
class Meta:
constraints = [
UniqueConstraint(
fields=("project", "node_a", "node_b"), name="unique_edge"
),
]
This catches if an Edge
is made with the same (A, B)
, but not if the same Node
s are put in reverse (B, A)
.
The validation function I’m trying to port to Constraint
s was:
def validate_unique(self, *args: Any, **kwargs: Any) -> None:
if self.project.edges.filter(
Q(node_a=self.node_a_id, node_b=self.node_b_id)
| Q(node_a=self.node_b_id, node_b=self.node_a_id)
).exists():
raise ValidationError(
f"Edges must be unique within a project: {self.node_a_id}|{self.node_b_id}"
)
This validation function validates that the Node
s are unique in both directions: (A, B)
or (B, A)
.
Is there a way to express this within a UniqueConstraint
?
Currently targeting Django 4.1. Cross posted from SO.