Search code examples
djangomany-to-many

Many to many relation entries not added by .add() method in Django


I am having a problem regarding adding entry to a many to many relation field. I have the models as follows

class Address(models.Model):
    id = models.AutoField(primary_key=True)
    country = CountryField(blank_label='(select country)', blank=False, null=False, verbose_name='Country')
    state = models.CharField(
        max_length=50,
        choices=STATE_CHOICES,
        verbose_name='State',
        blank=False,
        null=False
    )
    ...

class Volunteer(models.Model):
    userID = models.OneToOneField(User, on_delete=models.CASCADE, to_field='id', primary_key=True, related_name='volunteer')
    identificationNumber = models.CharField(max_length=50, unique=True, blank=False, null=False, verbose_name='Identification   Number')
    currentAddress = models.ManyToManyField(Address, related_name='volunteerCurrentAddress', verbose_name='Current Address', blank=False)
    permanentAddress = models.ManyToManyField(Address, related_name='volunteerPermanentAddress', verbose_name='Permanent Address', blank=False)
    ...

    def save(self, *args, **kwargs):
        self.slug = self.userID.username
        super(Volunteer, self).save(*args, **kwargs)

class TemporaryVolunteer(Volunteer):
    pass

And in the views, I get both the currentAddress and permanentAddress fields as a ManyToManyRelatedManager. They are temporaryVolunteer.currentAddress and temporaryVolunteer.permanentAddress. I use these to create a new Volunteer instance as

volunteer = Volunteer(...)
volunteer.save()
volunteer.currentAddress.add(temporaryVolunteer.currentAddress.all()[0])
volunteer.permanentAddress.add(temporaryVolunteer.permanentAddress.all()[0])
volunteer.save()

But when I do print(volunteer.currentAddress.all()) or print(volunteer.permanentAddress.all()), it returns an empty queryset. I also checked the admin site for confirmation and there are no entries of address on the volunteer instance. Is there any way the entries can be added with this approach?


Solution

  • The problem was in the design of the database. I had used a new class TemporaryVolunteer in order to store unverified accounts and later moved to the Volunteer class after they were verfied. As I had inherited TemporaryVolunteer from Volunteer class, the way Django handles Many to many relationships without making duplicates (Source: https://docs.djangoproject.com/en/3.0/topics/db/examples/many_to_many/) led to the problem of no entries being added in the corresponding Volunteer class.

    Initially, I checked this by copying all the members of Volunteer to TemporaryVolunteer. After verifying that it worked, I changed the database design as this is a bad approach and kept a boolean value isVerified in the Volunteer class and removed the TemporaryVolunteer class entirely.