Home > Enterprise >  Django ManyToOne reference multiple tables
Django ManyToOne reference multiple tables

Time:01-02

Right now I have the following model that I'd like to be used in different models (I want to store the day of the week and time in different models):

class DayTime(models.Model):
    # Side note: I saw that there is a DurationField and
    # was considering using that instead of the CharField below
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()

From the docs, I'd have to create a ForeignKey field in the above model to accommodate the ManyToOne reference.

Example:

class DayTime(models.Model):
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()
    modelA = models.ForeignKey(ModelA, on_delete=models.SET_NULL)
    modelB = models.ForeignKey(ModelB, on_delete=models.SET_NULL)

This doesn't sound right to me. Should I create different DayTime model instead?

Thanks in advance.

CodePudding user response:

The way you have it set up, ModelA can have many DayTimes but a particular DayTime object can only be associated with one ModelA object (and you can create another DayTime object with the same values, except pk, and any unique fields, and associate that DayTime with another ModelA object), and although it doesn't seem right to you, this might be what you want. The example in the docs have an Article object with a reporter as a ForeignKey since a reporter can have many Articles, but an Article only one reporter.

class DayTime(models.Model):
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()
    modelA = models.ForeignKey(ModelA, on_delete=models.SET_NULL)
    modelB = models.ForeignKey(ModelB, on_delete=models.SET_NULL)

In this second way, many ModelA objects can have a particular DayTime object, but a DayTime object can only be associated with one ModelA object (of course, that won't stop you from creating another DayTime object with the same field values (except the pk, and any fields you make unique). The same can be said for ModelB.

class DayTime(models.Model):
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()

class ModelA(models.Model):
    # some fields unique to ModelA
    daytime = models.ForeignKey(DayTime, on_delete=models.SET_NULL)

class ModelB(models.Model):
    # some fields unique to ModelB
    daytime = models.ForeignKey(DayTime, on_delete=models.SET_NULL)

Now if you need each ModelA object to have several DayTime objects, and you need a particular DayTime object to be associated with many ModelA objects as well, then you will need a many to many relationship:

class DayTime(models.Model):
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()

class ModelA(models.Model):
    # some fields unique to ModelA
    daytime = models.ManyToManyField(DayTime)

class ModelB(models.Model):
    # some fields unique to ModelB
    daytime = models.ManyToManyField(DayTime)

CodePudding user response:

I'm creating a DayTime model per class as needed. I wanted to create a model that would be easier to re-use, but if so I could just create an abstract base class and implement it. So far I haven't needed for more than one model anyway.

Example

class DayTime(models.Model):
    day = models.CharField(max_length=9, choices=DaysOfWeekTypeEnum.choices)
    time = models.TimeField()

    class Meta:
        abstract = True

class DayTimeModelA(DayTime):
    modelA = models.ForeignKey(
        'ModelA', related_name="day_times", on_delete=models.CASCADE)

class DayTimeModelB(DayTime):
    modelB = models.ForeignKey(
        'ModelB', related_name="day_times", on_delete=models.CASCADE)

Then this makes it easier for me to scale, create specific serializers, etc. If I want to query based on a day with two different models I can still do it.

  • Related