简体   繁体   中英

django is m2m relationship really necessary?

So I have two models like this.

class Channel(BaseModel):
    class Meta:
        verbose_name = 'channel'
        verbose_name_plural = 'channels'
        indexes = [
            models.Index(fields=['box', 'name'], name='channel_box_name_idx'),
        ]

    def __str__(self):
        return self.name

    def get_next_position(self):
        aggregate = self.box.channels.aggregate(models.Max('position'))
        return (aggregate['position__max'] or -1) + 1

    def save(self, *args, **kwargs):
        if self._state.adding:
            # we insert the object's position if
            # it hasn't been created yet. We need to do
            # this explicitly because django doesn't
            # allow more than one auto-field
            self.position = self.get_next_position()
            super(Channel, self).save(*args, **kwargs)
            return self.box.channels.add(self)
        super(Channel, self).save(*args, **kwargs)

    objects = models.Manager()
    name = models.CharField(max_length=100, validators=[MinLengthValidator(2)])
    box = models.ForeignKey('api_backend.Box', on_delete=models.CASCADE)
    position = models.PositiveSmallIntegerField(db_index=True)

    REQUIRED_FIELDS = [name, box]

class Box(BaseModel):
    class Meta:
        verbose_name = 'box'
        verbose_name_plural = 'boxes'
        indexes = [
            models.Index(fields=['owner'], name='box_owner_idx'),
            models.Index(fields=['owner', 'name'], name='box_name_owner_idx'),
        ]

    def __str__(self):
        return self.name

    objects = models.Manager()
    icon = models.ImageField(upload_to='icons/', storage=DefaultStorage)
    name = models.CharField(max_length=100, validators=[MinLengthValidator(2)])
    owner = models.ForeignKey('api_backend.User', on_delete=models.CASCADE)
    channels = models.ManyToManyField('api_backend.Channel', related_name='box_channels')

    REQUIRED_FIELDS = [name, owner]

Channel has an attribute box . And box has a m2m field channels . so in this type of relationship, whenever I create the channel with the box, I need to add the same to the box's m2m field channels . Is something like this really necessary? Like I need to have an extra table for the m2m field channels and even If I don't have it, I can access the same by doing box.channel_set

So, would there be any changes in the performance? Should I change my models structure? can someone please help me?

Can a channel have multiple boxes? If yes then a ManyToManyField is appropriate and the ForeignKey should be removed

If a ManyToManyField is not necessary since a Channel can only have one related Box then the ManyToManyField should be removed and the related accessor channel_set should be used

If you wish to have an attribute on Box instances named channels instead of channel_set that can be used to access any related Channel s you can provide related_name to the ForeignKey

class Channel(BaseModel):
    ...
    box = models.ForeignKey('api_backend.Box', on_delete=models.CASCADE, related_name='channels')
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM