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.