UniqueConstraint on three fields doesn't throw ValidationError
Opened this issue · 0 comments
iamjameswalters commented
I have a model with a UniqueConstraint across 3 different fields, and while the constraint works correctly at the database level, I expect this to bubble up as a ValidationError, and return the violation_error_message
back to the form, but instead I get a stacktrace/500.
Software versions
- Django: 4.2.16
- mssql-django: 1.5
- python: 3.12.6
- SQL Server: 15.0.2104.1
- OS: Windows 11
Model
class Client(models.Model):
# Put whatever you like here, it's just an FK below
class Location(models.Model):
# Put whatever you like here, it's just an FK below
class Alert(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
location = models.ForeignKey(
Location, on_delete=models.CASCADE, blank=True, null=True
)
title = models.CharField(max_length=100)
expire_date = models.DateTimeField()
details = models.TextField(blank=True, null=True)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["client", "location", "title"],
name="Unique_Alert_Per_Location_Per_Client",
violation_error_message="An alert with this title already exists for this location.",
),
]
Problem description and steps to reproduce
- Create a client (particulars of this model don't matter, it's a ForeignKey field on Alert model)
- Create an alert for this client with
title
ofTest
. - Try to create another alert for this client with
title
ofTest
.
Expected behavior and actual behavior
- This should result in the
violation_error_message
getting rendered to the Form's non-field errors. - Instead, we get a 500/stacktrace for a DB error
Error message/stack trace
('23000', "[23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Violation of UNIQUE KEY constraint 'Unique_Alert_Per_Location_Per_Client'. Cannot insert duplicate key in object 'dbo.clients_alert'. The duplicate key value is (4, <NULL>, Test). (2627) (SQLExecDirectW); [23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The statement has been terminated. (3621)")