Why are some records not added to the m2m table?
Why aren't some records being added to the m2m table? If the table already contains a record with a specific topic and system (service can be any), then the next addition of a record with a similar topic and system does not occur.
with transaction.atomic():
chat_topic = ChatTopics.objects.get(ct_id=chat_topic_id)
system = Systems.objects.get(sys_id=system_id)
service = ServiceCatalog.objects.get(sc_id=service_id)
chat_topic.ct_systems.add(system, through_defaults={"ctm_service": service})
I don't get any errors when run this code.
Expected result: Expected result
Actual result: Actual result
Models:
class Systems(BaseModel):
sys_id = models.AutoField(primary_key=True)
sys_name = models.CharField(max_length=256, unique=True, null=False)
def __str__(self):
return self.sys_name
class Meta:
verbose_name = "Systems"
verbose_name_plural = "Systems"
ordering = ['sys_id']
class ServiceCatalog(BaseModel):
sc_id = models.AutoField(primary_key=True)
sc_service = models.CharField(max_length=250, unique=True, null=False)
def __str__(self):
return self.sc_service
class Meta:
verbose_name = "Service catalog"
verbose_name_plural = "Service catalog"
ordering = ['sc_id']
class ChatTopics(BaseModel):
ct_id = models.AutoField(primary_key=True)
ct_systems = models.ManyToManyField(Systems, blank=True, through="chattopics_m2m")
ct_chat_id = models.CharField(max_length=20, null=False, blank=False)
ct_chat_name = models.CharField(max_length=50, null=False, blank=False)
ct_topic_id = models.CharField(max_length=10, null=True, default=None, blank=True)
ct_topic_name = models.CharField(max_length=50, null=True, default=None, blank=True)
def __str__(self):
return f'{self.ct_chat_name} ({self.ct_topic_name})'
class Meta:
verbose_name = 'Topics'
verbose_name_plural = 'Topics'
constraints = [
models.UniqueConstraint(fields=('ct_chat_id', 'ct_topic_id'), nulls_distinct=False, name='chattopics_ct_chat_id_ct_topic_id_unique')
]
class ChatTopics_m2m(BaseModel):
ctm_id = models.AutoField(primary_key=True)
ctm_chat_topic = models.ForeignKey(ChatTopics, on_delete=models.CASCADE, null=False)
ctm_system = models.ForeignKey(Systems, on_delete=models.CASCADE, null=False)
ctm_service = models.ForeignKey(ServiceCatalog, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
ordering = ['ctm_system']
This is the expected behavior of .add()
:
Adding a second time is OK, it will not duplicate the relation:
>>> a2.publications.add(p3)
What you probably want to do, which will also boost efficiency is using:
with transaction.atomic():
ChatTopics_m2m.objects.create(
system_id=system_id,
ctm_chat_topic_id=chat_topic_id,
ctm_service_id=service
)
and then the atomic transaction can probably get removed, since we do this with one query.