Opened 16 years ago

Closed 13 years ago

#8334 closed New feature (duplicate)

Allow add/create on m2m intermediate tables if all the non-FK fields have defaults or are NULLable

Reported by: Gergely Kontra Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: manytomany through default add create
Cc: ales.zoulek@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Russell Keith-Magee)

Add/create is currently disabled on m2m relations that use an intermediate table. This is due to the fact that values to populate the intermediate table cannot be provided using the add/create calls.

However, what if the intermediate model has reasonable default values, so
one can assign model A to B without extra info?

In my case, I just want to syncronize 2 databases, and I would like to
mark relationships, that are already synced. So, in my case, the
intermediate table contains a boolean, which defaults to false, and
will become true, when the data is synced.

In this case adding relations without explicitly creating the intermediate table would be great.

(based on this thread in the ML)

Change History (6)

comment:1 by Alex Gaynor, 16 years ago

Triage Stage: UnreviewedAccepted

Marking as accepted because it makes sense.

comment:2 by Russell Keith-Magee, 16 years ago

Description: modified (diff)
Summary: Allow add/create if all the non-FK fields have defaults or are NULLableAllow add/create on m2m intermediate tables if all the non-FK fields have defaults or are NULLable

Updated description and summary to describe the problem better.

comment:3 by Ales Zoulek, 15 years ago

Cc: ales.zoulek@… added

I did just a quick workaround. It's far from complete and universal code, but it works for me and could help some of you. :)

from django.db.models.fields.related import ReverseManyRelatedObjectsDescriptor as DjangoReverseManyRelatedObjectsDescriptor
from django.db import models



class ReverseManyRelatedObjectsDescriptor(DjangoReverseManyRelatedObjectsDescriptor):
    """Partialy supports add method in ManyToManyField with 'through'"""
    def __get__(self, *args, **kwargs):
        manager = super(ReverseManyRelatedObjectsDescriptor, self).__get__(*args, **kwargs)
        def add(*objs):
            manager._add_items(manager.source_col_name, manager.target_col_name, *objs)
        add.alters_data = True
        manager.add = add
        return manager


class ManyToManyField(models.ManyToManyField):

    def contribute_to_class(self, cls, name):
        ret = super(ManyToManyField, self).contribute_to_class(cls, name)
        setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self))
        return ret

# Continue with your models here. Use ManyToManyField class where needed.
class A(models.Model)
    b = ManyToManyField(B, through=AB)

...

comment:4 by (none), 15 years ago

milestone: post-1.0

Milestone post-1.0 deleted

comment:5 by Luke Plant, 13 years ago

Severity: Normal
Type: New feature

comment:6 by Johannes Dollinger, 13 years ago

Easy pickings: unset
Resolution: duplicate
Status: newclosed

Duplicate of #9475.

Note: See TracTickets for help on using tickets.
Back to Top