#22268: values_list() on a ManyToManyField returns extra None's when iterated over. -------------------------------------+------------------------------------- Reporter: k_sze | Owner: Type: Bug | anubhav9042 Component: Database layer | Status: assigned (models, ORM) | Version: master Severity: Normal | Resolution: Keywords: orm, values_list, | Triage Stage: Accepted ManyToManyField | Needs documentation: 0 Has patch: 0 | Patch needs improvement: 0 Needs tests: 0 | UI/UX: 0 Easy pickings: 0 | -------------------------------------+-------------------------------------
Comment (by k_sze): Actually the whole behaviour of `values()` and `values_list()` seems to be wrong once you mix M2M fields into the picture. I just tried creating more Class and Student objects: {{{ # New student, Joe Blo >>> joe_blo = Student(surname='Blo', given_name='Joe') >>> joe_blo.save() # New class, Discrete Mathematics >>> discrete_math = Class(name='Discrete Mathematics', school=concordia) >>> discrete_math.save() # Enroll both john_smith and joe_blo in discrete_math discrete_math.students.add(joe_blo) discrete_math.students.add(john_smith) }}} First, let's look at `values()` queries: {{{ >>> Class.objects.values() [{u'id': 1, 'name': u'Software Engineering', 'school_id': 1}, {u'id': 2, 'name': u'Computer Engineering', 'school_id': 1}, {u'id': 4, 'name': u'Discrete Mathematics', 'school_id': 1}] }}} That's 3 dictionaries because we now have 3 Class objects. That seems fine. On the other hand, why don't students appear here? {{{ >>> Class.objects.values('name', 'students') [{'students': 1, 'name': u'Software Engineering'}, {'students': None, 'name': u'Computer Engineering'}, {'students': 1, 'name': u'Discrete Mathematics'}, {'students': 2, 'name': u'Discrete Mathematics'}] }}} That's 4 dictionaries even though we only have 3 Class objects (soen, coen, and discrete_math). Can you imagine what would happen if the Class object had more M2M fields? The number of dictionaries returned would probably explode exponentially! Why aren't the students combined into a tuple or a list? Shouldn't it be 3 dictionaries like this: {{{ [ {'students': (1,), 'name': u'Software Engineering'}, {'students': (,), 'name': u'Computer Engineering'}, # Note the empty tuple for students, instead of None {'students': (1, 2), 'name': u'Discrete Mathematics'}, ] }}} Now, let's look at `values_list()` queries: {{{ >>> Class.objects.values_list() [(1, 1, u'Software Engineering'), (2, 1, u'Computer Engineering'), (4, 1, u'Discrete Mathematics')] }}} 3 tuples. Again, this seems fine except for the fact that students aren't included. {{{ >>> Class.objects.values_list('name', 'students') [(u'Software Engineering', 1), (u'Computer Engineering', None), (u'Discrete Mathematics', 1), (u'Discrete Mathematics', 2)] }}} 4 tuples even though we have 3 Class objects only! Shouldn't this be 3 tuples like this: {{{ [ (u'Software Engineering', (1,)), (u'Computer Engineering', (,)), # Note the empty tuple instead of None (u'Discrete Mathematics', (1, 2)), ] }}} -- Ticket URL: <https://code.djangoproject.com/ticket/22268#comment:15> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/063.b2d7eb0d7fa81b5101b3633481cc1673%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.