#24317: Deprecate field.rel, replace it with real field instances
-------------------------------------+-------------------------------------
     Reporter:  Anssi Kääriäinen     |                    Owner:  nobody
         Type:                       |                   Status:  new
  Cleanup/optimization               |
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Gabriel Canto de Souza):

 I also had a huge difficulty sorting out the fields of ._meta.get_fields()
 , what I was trying to achieve was get ONLY the reverse fields (because in
 our context every relationship is bidirectional, and everything is
 generic/auto generated)

 This gets really complicated with m2m that contain through tables, because
 not only you get the reverse m2m remote_field, but also the m2o
 relationship with the through table, so no only you have to figure out
 these are reverse, but group both the m2m and m2o that revert to the same
 relationship.

 This is the code I managed to come up with to get only the reverse rels:


   {{{#!python

  #I'm sure there's a better way of doing this
  #This is the documented way of getting reverse fields, but it also gets
 ManyToOne rel with the through table of forward m2m rels, so we have to
 filter them
  reverse_fields = [f for f in opts.get_fields() if f.auto_created and not
 f.concrete]
  reverse_m2m = [f for f in reverse_fields if f.__class__.__name__ ==
 'ManyToManyRel' and f.on_delete == None and not
 getattr(model,f.field.name,False)]
  #Also filtering the ManyToOne rel with the through table of the reverse
 m2m rels, because we need to differentiate them from reverse ManyToOne
 with other models(not through)
  reverse_m2m_through = [f for f in reverse_fields if f.__class__.__name__
 == 'ManyToOneRel'  and f.related_model in [f.through for f in reverse_m2m
 if getattr(f,'through',False)]]
  forward_m2m = [f.remote_field for f in opts.get_fields() if not
 f.auto_created and f.many_to_many]
  #Filtering the ManyToOne rels with the through table of forwards m2m
 rels, same logic as above
  forward_m2m_through = [f for f in reverse_fields if f.__class__.__name__
 == 'ManyToOneRel'  and f.related_model in [f.through for f in forward_m2m
 if getattr(f,'through',False)]]
  reverse_fields_final = itertools.chain(reverse_m2m, [f for f in
 reverse_fields if f not in itertools.chain(reverse_m2m,
 reverse_m2m_through, forward_m2m, forward_m2m_through)])
   }}}

 I propose to add a new attribute ''is_reverse = True/False'' to facilitate
 this, of course this solution works in my context point of view, there
 might be a better approach to this

--
Ticket URL: <https://code.djangoproject.com/ticket/24317#comment:17>
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/066.667c1cb380d50fade1e9d1f03958ab8d%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to