I have 2 models in my application:
My goal is to associate many towers to a user using an intermediate table because I need to add a period of time.
So I have something like this in my models:
class Tower(models.Model):
name = models.CharField(max_length=128)
class User(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField('Tower', through='Dates')
class Dates(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
tower = models.ForeignKey('Tower', on_delete=models.CASCADE)
begin_date = models.DateTimeField()
end_date = models.DateTimeField()
But my goal was to have the field tower in class Dates to a many-to-many like this:
tower = models.ManyToManyField('Tower', blank=True)
So that i can associate many towers to a user in a certain period. But unfortunately django says that i need to use forgeignkey to Tower and User classes.
Have any solution for this? To apply directly the many-to-many field in the intermediate table? Or I must create a new class, sort of a GroupTower, that have a many-to-many field to the Tower class? Something like this:
class Tower(models.Model):
name = models.CharField(max_length=128)
class GroupTower(models.Model):
tower = models.ManyToManyField('Tower', blank=True)
class User(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField('Tower', through='Dates')
class Dates(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
tower = models.ForeignKey('GroupTower', on_delete=models.CASCADE)
begin_date = models.DateTimeField()
end_date = models.DateTimeField()
Thanks in advance.
There is so many ways that you can design the database.
An example:
class Tower(models.Model):
name = models.CharField(max_length=128)
class User(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField('UserTower')
class UserTower(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
tower = models.ManyToManyField('Tower')
begin_date = models.DateTimeField()
end_date = models.DateTimeField()
In this design you can add many UserTower
instances to a user and each UserTower
instance can have many towers.
Now if you query the members for a user:
User.objects.get(pk=1).members.all()
You will have members grouped by periods of time if you saved them this way but it requires you to write some codes to avoid duplicates for begin_date
, begin_date
and user
.
And now if you need towers:
user_members = User.objects.get(pk=1).members.all().values_list('tower', flat=True)
towers = Tower.objects.filter(pk__in=user_members).distinct()
This design is okay only if you really don't want duplicates with same begin_date
and begin_date
which i can't find a reason for.
You can still have all the features if you add multiple instances with same begin_date
, begin_date
and user
but different tower
.