saf
saf

Reputation: 259

Issues with intermediary many to many field in Django

I am inserting data in models which are related with other models via Many-to-Many relations. I was trying to use add() to add values in many-to-many filed but that doesn't work and raise this error Cannot set values on a ManyToManyField which specifies an intermediary model.

I read the docs and found out that we cannot use set(), add(), create() for intermediary model.

Here are my models :

class Venue(MPTTModel):
    organisation = models.ForeignKey(Organisation, verbose_name=_('organisation'))
    name = models.CharField(_('name'), max_length=100)
    description = models.TextField(_('description'), null=True, blank=True)
    address = models.ForeignKey(Address, verbose_name=_('address'))
    org_users = models.ManyToManyField(PortalUser, through='OrgMapping', verbose_name=_('org users'))
    modified_at = models.DateTimeField(_('modified at'), auto_now=True)

class OrgMapping(models.Model):
    host_group = models.ForeignKey(OrgHostGroups, verbose_name=_('host group'))
    org_user = models.ForeignKey(PortalUser, verbose_name=_('org user'))
    venue = models.ForeignKey(Venue, verbose_name=_('venue'))
    org_roles = models.ManyToManyField(OrgRole, verbose_name=_('org roles'))
    org_permissions = models.ManyToManyField(OrgPermission, verbose_name=_('org permissions'), blank=True)
    created_at = models.DateTimeField(_('created at'), auto_now_add=True)
    modified_at = models.DateTimeField(_('modified at'), auto_now=True)
    is_deleted = models.BooleanField(_('is deleted'), default=False)



def create_org_venue(org, name, desc, address, org_users):
    """
    org_users must be a list or portal users pk's
    """

    parent = get_or_none(Venue, organisation__name='TeraMatrix')
    venue = Venue(organisation=org,
                            name=name,
                            description='Head Office',
                            address=address)
    venue.save()
    # save org_users to above venue
    for user in org_users:
        # venue.org_users.add(user)
        venue.org_users = get_or_none(PortalUser,pk=user)
        venue.save()
    return venue

Now If I'll try to craete venue using create_org_venue it will raise error. Any idea how I can do this

Edit :-

class OrgHostGroups(MPTTModel):
    organisation = models.ForeignKey(Organisation, verbose_name=_('organisation'))
    name = models.CharField(_('name'), max_length=100)
    description = models.TextField(_('description'), null=True, blank=True)
    org_users = models.ManyToManyField(PortalUser, through='OrgMapping', verbose_name=_('org users'))
    venues = models.ManyToManyField(Venue, through='OrgMapping', verbose_name=_('venues'))

As you can see Venue model mapped through orgmapping and which further need orghostgroup and it needs venues and mapping again. So we can say that a circular relationship.

Upvotes: 0

Views: 77

Answers (1)

Alasdair
Alasdair

Reputation: 308789

It's not possible to use add() when using an intermediary model, because that wouldn't let you specify values for the extra fields on the intermediary model.

Instead, just create an instance of the intermediary model.

OrgMapping.objects.create(
    venue=venue,
    org_user=user,
    # set all the other required OrgMapping fields here
)

See the docs on extra fields on many-to-many relationships for more info.

Upvotes: 1

Related Questions