#21612: queryset update ignores to_field on foreign keys
-------------------------------+--------------------
     Reporter:  berndtj@…      |      Owner:  nobody
         Type:  Uncategorized  |     Status:  new
    Component:  Uncategorized  |    Version:  1.5
     Severity:  Normal         |   Keywords:
 Triage Stage:  Unreviewed     |  Has patch:  0
Easy pickings:  0              |      UI/UX:  0
-------------------------------+--------------------
 When issuing a batch update on a queryset, the to_field of the related
 model is ignored in some cases.  For instance, I am using a uuid field as
 a foreign key field (to_field).  When I try to update the relationship,
 the pk is used for in the foreign key column (<foreign_model>_id) instead
 of the uuid.  For example given a queryset of BracketVolumeTemplates which
 have a parent field which refers to a BracketVolume:


 {{{
 # The field definition
 parent = models.ForeignKey(
         'BracketVolume', null=True, blank=True, to_field='uuid',
         related_name='parent_templates')

 # We start with a queryset of one which has a BracketVolumeTemplate which
 refers to a BracketVolume via the parent filed
 ipdb> queryset
 [<BracketVolumeTemplate [snapshot based] ID:
 10dc67d94f8347d195e25eca6f3c22bb - created by [email protected]>]
 ipdb> queryset[0].parent
 <BracketVolume [snapshot] Requested State: DELETED ID:
 2de07185d9744fdd83b5f683dfe5a2aa - created by [email protected]>

 # The parent_id is correctly set as the UUID
 ipdb> queryset[0].parent_id
 u'2de07185d9744fdd83b5f683dfe5a2aa'

 # We are updating with the kwargs as follows
 ipdb> kwargs
 {'parent': <BracketVolume [snapshot] Requested State: AVAILABLE ID:
 62b72525425b4252925ba9ce48d42428 - created by [email protected]>}
 ipdb> queryset.update(**kwargs)
 1

 # Wait, parent_id should be the UUID, but instead the pk is used for the
 foreign key
 ipdb> queryset[0].parent_id
 u'3'

 # Now the relationship is broken
 ipdb> queryset[0].parent
 *** DoesNotExist: BracketVolume matching query does not exist. Lookup
 parameters were {'uuid__exact': u'3'}

 # Queryset hides the db_columns, so we can't work around directly
 ipdb> queryset.update(parent_id='2de07185d9744fdd83b5f683dfe5a2aa')
 *** FieldDoesNotExist: BracketVolumeTemplate has no field named
 'parent_id'

 # The below workaround does work...
 ipdb> queryset.update(parent='2de07185d9744fdd83b5f683dfe5a2aa')
 1
 ipdb> queryset[0].parent
 <BracketVolume [snapshot] Requested State: DELETED ID:
 2de07185d9744fdd83b5f683dfe5a2aa - created by [email protected]>
 ipdb> c
 }}}

 I can work around this by adding the following code in my update code, but
 it's not ideal:

 {{{
 for key in kwargs:
             field = queryset.model._meta.get_field(key)
             if isinstance(field, ForeignKey):
                 model = kwargs[key]
                 if not model:
                     continue
                 rel_att = field.rel.field_name
                 kwargs[key] = getattr(model, rel_att)
         queryset.update(modified_by=modified_by_id, **kwargs)
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/21612>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/060.808396ae4baae2f4cf4afb3aa9a3d850%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to