I am trying to understand how to use a OnetoOne relation with unique_together. Currently trying to make use of them in my serializer and view with no success.
Models:
class Employees(models.Model):
name = models.CharField()
position = models.CharField()
phone = models.IntegerField()
class WorkSchedule(models.Model):
employee = models.OneToOneField('Employees')
workday = models.DateTimeField()
class Meta:
unique_together = (('employee', 'workday'),)
First question: Since the relation is OneToOne if i didn't have unique_together then each employee could appear in WorkSchedule once. However since i have unique_together this is not the case anymore. Correct?
Second Question: How would i use such models to return all employees and their workschedules like this
{
"employees": [
{
"employee": "John",
"workschedule": [
{
workday: "2022-03-03"
},
{
workday: "2022-03-04"
}
},
{
"employee": "Tom",
"workschedule": [
{
workday: "2022-03-03"
},
{
workday: "2022-03-04"
}
}
}
I was able to do this with using a ForeignKey(no unique_together) and a Nested Serializer however i wasn't able to do it with using the two models as they are above.
First question: Since the relation is OneToOne if i didn't have
unique_together
then each employee could appear in WorkSchedule once. However since i have unique_together this is not the case anymore. Correct?
No: a OneToOneField
is a ForeignKey
with a uniqness constraint. The fact that you later define an extra constraint does not matter. This thus means that your unique_together
has no impact: since the OneToOneField
already guarantees that the employee
is unique, this implies that the combination with the workday
will be unique, even without specifying a unique_together
.
You thus should thus use a ForeignKey
, so:
class WorkSchedule(models.Model):
employee = models.ForeignKey('Employees', on_delete=models.CASCADE)
workday = models.DateTimeField()
class Meta:
constraints = [
models.UniqueConstraint(fields=['employee', 'workday'], name='unique_employee_workday')
]
Second Question: How would i use such models to return all employees and their workschedules like this.
By using a ForeignKey
. It make no sense here to use a OneToOneField
: this only makes sense if each WorkSchedule
has exactly one Employee
, and each Employee
has at most one WorkSchedule
.
Note: As the documentation on
unique_together
[Django-doc] says, theunique_together
constraint will likely become deprecated. The documentation advises to use theUniqueConstraint
[Django-doc] from Django's constraint framework.