Opened 3 years ago

Closed 3 years ago

#32279 closed Bug (invalid)

Is this a bug with the ManyToMany self referencing field?

Reported by: Conrad Owned by: nobody
Component: Uncategorized Version: 3.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I asked this on [stack overflow](https://stackoverflow.com/questions/65338714/why-doesnt-this-script-add-my-structure-correctly-to-django), but got no answers, so I think it might be a bug?

I encountered a pretty weird problem with a ManyToManyField in Django today. When automatically reading input data from a dict the ManyToMany field gets populated falsely. My model is for this example pretty simple the UnitType has a name and 4 ManyToMany fields, one of them beeing possible_children = models.ManyToManyField('self', related_name='UnitTypeChildren', blank=True). When I run my management command which I set up for this minimal example I run (subtypes is truncutaded because there are a lot of values and everything with this works):

building_subtypes = {
    'garage/ parking': {'subtypes': [...]},
    'room': {'subtypes': [...], 'child': ['room']},
    'apartment': {'subtypes': [...]},
    'floor': {'subtypes': [...], 'child': ['room', 'apartment', 'garage/ parking']},
    'building': {'subtypes': [...], 'child': ['room', 'floor', 'apartment', 'garage/ parking']},
    'address': {'subtypes': [...], 'child': ['building', 'apartment', 'garage/ parking']},
    'business': {'subtypes': [...]},
    'other': {'subtypes': [...]}
}


for typ in building_subtypes:
    ut, new = UnitType.objects.get_or_create(name=typ)
    for subtype in building_subtypes[typ]['subtypes']:
        UnitSubType.objects.get_or_create(name=subtype, unit_type=ut)
        if 'child' in building_subtypes[typ]:
            for child in building_subtypes[typ]['child']:
                child_ut, new = UnitType.objects.get_or_create(name=child)
                print(subtype.name + ' ' + child_ut.name)  # Prints correctly
                ut.possible_children.add(child_ut)

# Check if it worked
for ut in UnitType.objects.all():
    childstring = ""
    for child in ut.possible_children.all():
        childstring += str(child) + ', '
    print(ut.name + ': ' + childstring)  # Prints alternate structure

When accessing Django admin after this script the structure is not at all what I intended or expected but seemingly random. I tried reading the data in from a different dict, reordering the dict to avoid dependency issues, adding null=True to the field, because of the values which are populated but shouldn't be. Furthermore I tried saving the object after each add and after all adds but the results are the same. Right now I'm a bit confused. It's not that I couldn't do it another way, it's more that I am asking myself why this occurs?

The output is as follows:

room room
floor room
floor apartment
floor garage/ parking
building room
building floor
building apartment
building garage/ parking
address building
address apartment
address garage/ parking

garage/ parking: floor, building, address, 
room: room, floor, building, 
apartment: floor, building, address, 
floor: garage/ parking, room, apartment, building, 
building: garage/ parking, room, apartment, floor, address, 
address: garage/ parking, apartment, building, 
business: 
other:

Change History (1)

comment:1 by Mariusz Felisiak, 3 years ago

Resolution: invalid
Status: newclosed

Everything works properly, ManyToManyField is a symmetrical relation.

Please don't use Trac as a support channel. Closing per TicketClosingReasons/UseSupportChannels.

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