Opened 15 years ago
Closed 15 years ago
#12406 closed (worksforme)
Model Meta ordering bug with manytomany field
Reported by: | pbzrpa | Owned by: | nobody |
---|---|---|---|
Component: | Uncategorized | Version: | 1.1 |
Severity: | 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
There seems to be a problem with ordering in a model meta class when you have a manytomany field in the model. It sorts the queryset grouped by the manytomany field.
Example:
class RelationType(models.Model): name = models.CharField(max_length = 30) editable = models.BooleanField(default=True) def __unicode__(self): return u'%s' % self.name class Relation(models.Model): code = models.CharField(max_length = 20, primary_key = True) relationtype = models.ManyToManyField(RelationType) short_name = models.CharField(max_length = 30) full_name = models.CharField(max_length = 100, null = True, blank = True) pref_comm = models.ForeignKey(RelationCommunicationType, verbose_name = 'Perferred Comm') def __unicode__(self): return u'%s' % self.short_name class Meta: ordering = ('short_name',)
When you do Relation.objects.all() it sorts according to the short name but in lists grouped by the manytomany field.
So you would have a result like:
Short Name | Type ab | Sup abc | Sup bcd | Sup abcd | Cust
instead of
Short Name | Type ab | Sup abc | Sup abcd | Cust bcd | Sup
Change History (4)
comment:1 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:2 by , 15 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Thank you for your response.
In [6]: Relation.objects.all() Out[6]: [<Relation: Alcagen>, <Relation: Amazitech Computers>, <Relation: Axiz>, <Relation: Centurion Technology Cc>, <Relation: Compu Cable Projects>, <Relation: Eco Technology>, <Relation: Frog>, <Relation: Game World>, <Relation: Infosat>, <Relation: Klj Consulting Cc>, <Relation: Micro Vision Computers>, <Relation: Service Parts Logistics>, <Relation: Sound And Lighting>, <Relation: Tarsus>, <Relation: Wirecom Pty Ltd>, <Relation: Adele'S Escorts>, <Relation: Aga Air Conditioning>, <Relation: Aga Aircon Services>, <Relation: Aga Cape Town>, <Relation: Akhuna Mathata>, '...(remaining elements truncated)...'] In [7]: from django.db import connection In [8]: connection.queries[-1] Out[8]: {'sql': u'SELECT `relations_relation`.`code`, `relations_relation`.`short_name`, `relations_relation`.`full_name`, `relations_relation`.`pref_comm_id` FROM `relations_relation` ORDER BY `relations_relation`.`short_name` ASC LIMIT 21', 'time': '0.002'}
Please note that in the queryset the order changes at <Relation: Wirecom Pty Ltd>. The first set of records until <Relation: Wirecom Pty Ltd> have one relationtype manytomany linked to it and the rest have a different manytomany relationtype. Here is another copy of my model.
class RelationType(models.Model): name = models.CharField(max_length = 30) editable = models.BooleanField(default=True) def __unicode__(self): return u'%s' % self.name class Relation(models.Model): code = models.CharField(max_length = 20, primary_key = True) relationtype = models.ManyToManyField(RelationType) short_name = models.CharField(max_length = 30) full_name = models.CharField(max_length = 100, null = True, blank = True) pref_comm = models.ForeignKey(RelationCommunicationType, verbose_name = 'Perferred Comm') def __unicode__(self): return u'%s' % self.short_name def type_split(self): return ",".join( [ x.name for x in self.relationtype.all()] ) class Meta: ordering = ('short_name',)
comment:3 by , 15 years ago
Here is the result of the RelationType queryset.
In [9]: from cc.relations.models import RelationType In [10]: RelationType.objects.all() Out[10]: [<RelationType: Customer>, <RelationType: Supplier>, <RelationType: Branch>]
The records up to <Relation: Wirecom Pty Ltd> have a relationtype <RelationType: Supplier>, the rest have <RelationType: Customer>.
Hope that helps.
comment:4 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
Please forgive me for wasting your time. I found the problem. During my import all the Supplier records got a space in front of the short_name and that is why it was sorting like that. Will remember that in future. Sorry and thank you for your trouble.
I think you've left something key out of how to recreate this problem. Using the models you show,
Relation.objects.all()
won't do anything to even retrieve any of the relatedRelationType
instances. The DB query generated is quite simple, orders by short name, and produces the correct results:What code did you use to generate the tables show above? That's likely where the problem lies.