#31639: F objects do not error when referencing transforms.
-------------------------------------+-------------------------------------
     Reporter:  Baptiste Mispelon    |                    Owner:  Srinivas
                                     |  Reddy Thatiparthy
         Type:  Bug                  |                   Status:  assigned
    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 Tim Park):

 Hey guys - Here is an outline of a brute force solution for raising a
 {{{ValueError}}} if a lookup is passed into {{{F()}}}.

 **Thought Process**
 1. We init the F() object with a parameter {{{name}}}
 2. If a lookup value is found in {{{name}}}, raise ValueError
 3. Otherwise, continue instantiating the F() object as normal

 So the next step is figuring out how to check if a lookup value is
 contained in {{{name}}}.

 1. Lookup expressions follow the format of {{{<fieldname>__<lookup>}}}
 2. First, I wanted to raise the error if {{{name}}} contained two
 underscores {{{__}}} but I realized we use double underscores for
 referencing foreign keys as shown in our example of
 {{{client__bills__issued_on}}}.
 2. Per docs linked below, lookups are ALWAYS evaluated last. So if we
 split the {{{name}}} string on character {{{__}}}, the last portion of
 that split would be a potential lookup expression. Check if that potential
 lookup expression exists in Django's actual lookup expressions. I could
 follow this process to check for transforms within {{{name}}}

 **Conclusion**
 So this technically works but it seems hacky because it won't take into
 account situations where users define their own custom lookups.

 Let me know if I am missing something obvious here. Happy to take
 hints/direction to help explore the right places.

 Thanks!

 **References**
 Lookup Positioning Docs [https://docs.djangoproject.com/en/3.0/howto
 /custom-lookups/#how-django-determines-the-lookups-and-transforms-which-
 are-used]

 List of All Django Field Lookups
 [https://docs.djangoproject.com/en/3.0/ref/models/querysets/#field-
 lookups]

 Code for F()
 
[https://github.com/django/django/blob/58a336a674a658c1cda6707fe1cacb56aaed3008/django/db/models/expressions.py#L560]
 {{{
 class F(Combinable):

     def __init__(self, name):
         lookups = {'exact', 'iexact', 'contains', 'icontains', 'in', 'gt',
                    'gte', 'lt', 'lte', 'startswith', 'istartswith',
 'endswith',
                    'iendswith', 'range', 'date', 'year', 'iso_year',
 'month', 'day',
                    'week', 'week_day', 'quarter', 'time', 'hour',
 'minute', 'second',
                    'isnull', 'regex', 'iregex'}

         if name.split("__")[-1] in lookups:
             raise ValueError("F() objects do not support lookups")

         self.name = name
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31639#comment:6>
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.1106bbfa9cab1e075cdc07da528817f7%40djangoproject.com.

Reply via email to