#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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.1106bbfa9cab1e075cdc07da528817f7%40djangoproject.com.

Reply via email to