BertrandBordage / django-super-inlines

Adds useful features to inlines, such as the ability to nest them.
BSD 3-Clause "New" or "Revised" License
75 stars 8 forks source link

No update when using nested inline generic foreign keys #9

Open gehilley opened 9 years ago

gehilley commented 9 years ago

Hi Bertrand,

First, super_inlines has been a wonderful addition to my project. Thanks very much for a clean, nice package.

Second, I may have uncovered an issue when trying to inline models referenced with generic foreign keys. Here are test model and admin files that reveal this issue:


models.py:

from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.db.models.fields import CharField

class ModelA(models.Model):

float_value = models.FloatField()
model_b = models.ForeignKey('ModelB')

class ModelB(models.Model):

name = CharField(max_length=30)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

class ModelC(models.Model):

name = CharField(max_length=30)
float = GenericRelation(ModelB, related_query_name = 'model_b')
model_d = models.ForeignKey('ModelD', null = True)

class ModelD(models.Model):

pass

admin.py:

from super_inlines.admin import SuperInlineModelAdmin, SuperModelAdmin from django.contrib.contenttypes.admin import GenericStackedInline from .models import ModelA, ModelB, ModelC, ModelD from django.contrib.admin import TabularInline, StackedInline, site

class ModelAInlineModelAdmin(SuperInlineModelAdmin, TabularInline): model = ModelA fields = ('float_value',) extra = 1

class ModelBInlineModelAdmin(SuperInlineModelAdmin, GenericStackedInline): model = ModelB fields = ('name', ) inlines = (ModelAInlineModelAdmin,) extra = 1

class ModelCInlineModelAdmin(SuperInlineModelAdmin, StackedInline): model = ModelC fields = ('name', ) inlines = (ModelBInlineModelAdmin,) extra = 1

class ModelDModelAdmin(SuperModelAdmin): model = ModelD fields = () inlines = (ModelCInlineModelAdmin,)

class ModelCModelAdmin(SuperModelAdmin): model = ModelC fields = ('name',) inlines = (ModelBInlineModelAdmin,)

site.register(ModelD, ModelDModelAdmin) site.register(ModelC, ModelCModelAdmin)


When populating the ModelA values through the ModelDModelAdmin, the ModelA values do not update. However, when updating the ModelA values through the ModelCModelAdmin, the ModelA values update correctly. Thus, it seems that the SuperInlineModelAdmin may not be referencing the generic foreign key correctly (although the SuperModelAdmin does).

Thanks in advance for any help you can lend.

best, george.

gehilley commented 9 years ago

Hi Again Bertrand,

A quick update. During further testing, this seems a general property of a 4-level nested inline, rather than being the result of a GFK. If I can pinpoint the problem and develop a solution, I will post the solution here.

george.

qsmits commented 8 years ago

I just ran in to this problem as well, it has to do with the naming of the input fields in the inline admins. These are always referencing the first inline, for example, I have a product database with quite an extensive tree-like datastructure and in all of the 4th-level inlines, the names are similar to this:

prdcts-product_languages-0-0-ean prdcts-product_languages-0-1-ean (For the first product version)

For the inline for second product version, I would expect:

prdcts-product_languages-1-0-ean prdcts-product_languages-1-1-ean

But they are identical to the names from the first one.

So, multiple inlines for the same product 'version' work, but if you have multiple higher level records in the tree, the 4th level records always point to the first one.