#24156 closed Bug (fixed)
inherited manytomany.all() empty when 2 or more inherited model from abstract one
Reported by: | Timothée Mazzucotelli | Owned by: | Andriy Sokolovskiy |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | inherit asbtract manytomanys |
Cc: | me@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If you set a ManyToMany field in an abstract model, and then you use this model as inheritance for 2 or more sub-models (non-abstracts), you will not be able to use submodel_instance.manytomany_field.all() anymore (actually it will work but return an empty list).
Here is an example of code producing this "bug":
from django.db import models class Something(models.Model): name = models.CharField('something', max_length=255) def __unicode__(self): return self.name class AbstractModel(models.Model): manythings = models.ManyToManyField( Something, verbose_name='manythings', related_name='+', blank=True, null=True) class Meta: abstract = True class BugModel1(AbstractModel): custom1 = models.CharField('custom_field', max_length=255) class BugModel2(AbstractModel): custom2 = models.CharField('custom_field', max_length=255)
When you add a Something instance to the manythings field of a BugModelN instance, it is correctly added (I was able to confirm this by trying to delete the object through admin interface: it lists the foreign key related object that will be deleted on cascade), but when you want to get it through the all() method of the manytomany field, it returns an empty list.
I am not sure if it is a bug since I was not able to get any raised error or else through debug. Maybe a voluntary behavior or a forgotten use case?
(Django 1.7.3)
Change History (8)
comment:1 by , 10 years ago
Summary: | inherited manytomany.all() empty when 2 or more inherited model from asbtract one → inherited manytomany.all() empty when 2 or more inherited model from abstract one |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
Version: | 1.7 → master |
---|
I faced with this issue too.
My example:
class ModelA(models.Model): field1 = models.TextField(blank=True) class AbstrMdl(models.Model): class Meta: abstract = True field1 = models.ManyToManyField('ModelA', related_name='+') class ModelB(AbstrMdl): field2 = models.TextField(blank=True) class ModelC(AbstrMdl): field2 = models.TextField(blank=True) --- In [1]: from myapp.models import ModelA, ModelB In [2]: a = ModelA.objects.create(field1='bla bla') In [3]: b = ModelB.objects.create() In [4]: b.field1.all() Out[4]: [] In [5]: b.field1.add(a) In [6]: b.field1.all() Out[6]: []
Data is saving to database, but queryset is empty because it is filtered by something like +__in=
.
Investigation showed me that problem is near django.db.models.fields.related.RelatedField#related_query_name
.
For example this diff fixed my issue, but some tests are failing, so I will investigate deeper.
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 4569037..345a83c 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -371,7 +371,10 @@ class RelatedField(Field): Define the name that can be used to identify this related object in a table-spanning query. """ - return self.remote_field.related_query_name or self.remote_field.related_name or self.opts.model_name + if self.remote_field.is_hidden(): + return self.remote_field.related_query_name or self.opts.model_name + else: + return self.remote_field.related_query_name or self.remote_field.related_name or self.opts.model_name
comment:3 by , 10 years ago
Cc: | added |
---|
comment:4 by , 10 years ago
In fact, list is not empty.
In my example it get empty list because ModelB
results are empty.
That means that if I will inherit 2 or more models from abstract one,
ModelA
and ModelB
will have the result of ModelC
queryset.
comment:5 by , 10 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:6 by , 10 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Seems like a bug.