• 
      

    Add support for prefixing query expressions

    Review Request #7774 — Created Nov. 17, 2015 and submitted

    Information

    Djblets
    master
    850d88a...

    Reviewers

    A new utility method, prefix_q, has been added to facilitate
    prefixing of query expressions. Query expressions, or (Q()
    expressions) are Django's way of building the WHERE (and related)
    clauses when querying for models.

    If a foreign key fk exists from a model A to B (that is, A.fk
    points at an instance of B), then a query expression that is used
    to filter instances of B can be used with A via prefix_q:

    q_a = prefix_q('fk', q_b)
    

    This allows complex queries that select one model to be reused to
    select related models very easily.

    Ran unit tests.

    Description From Last Updated

    Col: 13 E122 continuation line missing indentation or outdented

    reviewbot reviewbot

    Col: 13 E122 continuation line missing indentation or outdented

    reviewbot reviewbot

    I think I'd like more explanation about what "Prefix a Q expression" means. Can you give an example?

    david david

    Just calling six.binary_type will explode if there's any non-ascii characters in there. Maybe that's what you want, but otherwise, perhaps …

    david david

    It's pretty weird to see the u'' in there. Is that just something funky with Q.__str__?

    david david

    How about explaining that: B.objects.filter(prefix_q(Q(field='value'), 'a')) is the same as: B.objects.filter(Q(a__field='value'))

    david david

    "Return," not "Get." I don't think it's worth using Sphinx references for things like "None" in a summary.

    chipx86 chipx86

    For these, maybe: :py;meth:`Manager.get <django.db.models.manager.Manager.get>

    chipx86 chipx86

    """ is indented too far.

    chipx86 chipx86

    I feel like this doesn't describe this well enough. The example does, but I'd like to see a bit more …

    chipx86 chipx86

    This is backwards. It's title <reference>.

    chipx86 chipx86

    This should be: Example: .. code-block:: python <example here> In other files, this is also after Args and Returns.

    chipx86 chipx86

    Sentence casing.

    chipx86 chipx86

    Sentence casing.

    chipx86 chipx86

    Are you sure about this reference? The Django docs are showing it under django.db.models.Q.

    chipx86 chipx86

    I don't know that :py:data: is really appropriate for things like True, False, or None. It's really intended for module-level …

    chipx86 chipx86

    It's not clear to me, reading the unit tests and the code, whether all these cases are covered. Probably because …

    chipx86 chipx86

    Any reason we don't just use isinstance? Generally, it's nice not to restrict to a specific base type, so long …

    chipx86 chipx86

    Is this needed? Are we aware of cases where it must be a byte string? I thought Unicode strings were …

    chipx86 chipx86

    Unit test suite docstrings are in the form of: "Unit tests for module.path.to.thing." Also, trailing period.

    chipx86 chipx86

    The docstrings should all mention prefix_q.

    chipx86 chipx86

    Should be "Return a model instance"

    david david
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    brennie
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. djblets/db/tests/test_query.py (Diff revision 2)
       
       
      Show all issues
      Col: 13
       E122 continuation line missing indentation or outdented
      
    3. djblets/db/tests/test_query.py (Diff revision 2)
       
       
      Show all issues
      Col: 13
       E122 continuation line missing indentation or outdented
      
    4. 
        
    brennie
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    david
    1. 
        
    2. djblets/db/query.py (Diff revision 3)
       
       
      Show all issues

      I think I'd like more explanation about what "Prefix a Q expression" means. Can you give an example?

    3. djblets/db/query.py (Diff revision 3)
       
       
      Show all issues

      Just calling six.binary_type will explode if there's any non-ascii characters in there. Maybe that's what you want, but otherwise, perhaps use .encode('utf-8')?

    4. djblets/db/tests/test_query.py (Diff revision 3)
       
       
       
      Show all issues

      It's pretty weird to see the u'' in there. Is that just something funky with Q.__str__?

      1. It calls repr on its elements, and so it renders as a unicode string.

    5. 
        
    brennie
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    brennie
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    david
    1. 
        
    2. djblets/db/query.py (Diff revision 5)
       
       
      Show all issues

      How about explaining that:

      B.objects.filter(prefix_q(Q(field='value'), 'a'))
      

      is the same as:

      B.objects.filter(Q(a__field='value'))
      
    3. 
        
    brennie
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    brennie
    chipx86
    1. 
        
      1. The review request description should go into more detail on this. It feels to me to be descriptive only if you already know what this change is about.

    2. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      "Return," not "Get."

      I don't think it's worth using Sphinx references for things like "None" in a summary.

    3. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      For these, maybe:

      :py;meth:`Manager.get <django.db.models.manager.Manager.get>
      
    4. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      """ is indented too far.

    5. djblets/db/query.py (Diff revision 6)
       
       
       
       
       
       
      Show all issues

      I feel like this doesn't describe this well enough. The example does, but I'd like to see a bit more about how this is useful.

      It should also go into the cloning behavior and defaults.

    6. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      This is backwards. It's title <reference>.

    7. djblets/db/query.py (Diff revision 6)
       
       
       
       
      Show all issues

      This should be:

      Example:
          .. code-block:: python
      
             <example here>
      

      In other files, this is also after Args and Returns.

    8. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      Sentence casing.

    9. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      Sentence casing.

    10. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      Are you sure about this reference? The Django docs are showing it under django.db.models.Q.

      1. https://github.com/django/django/blob/master/django/db/models/query_utils.py#L45

    11. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      I don't know that :py:data: is really appropriate for things like True, False, or None. It's really intended for module-level data, with the implication being the current module. Does it result in actual links to the Python docs?

    12. djblets/db/query.py (Diff revision 6)
       
       
       
       
       
      Show all issues

      It's not clear to me, reading the unit tests and the code, whether all these cases are covered. Probably because parts involve internal Q knowledge, but I want to make sure we have 100% coverage of this.

    13. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      Any reason we don't just use isinstance? Generally, it's nice not to restrict to a specific base type, so long as the thing coming in behaves like the expected type.

      Also, this shouldn't be an assertion, it should raise an exception if it's not a valid type. Assertions are for internal code that should always be correct, and are just to verify something isn't screwed up (like an internal function calling another internal function with some certain state).

      1. This should never ever be anything other than a tuple due to the internals of Q.

    14. djblets/db/query.py (Diff revision 6)
       
       
      Show all issues

      Is this needed? Are we aware of cases where it must be a byte string? I thought Unicode strings were fine here.

      If this is indeed required, we need to have a unit test for it.

      1. Q() objects created as Q(key=val) will have key as a bytestring.

    15. djblets/db/tests/test_query.py (Diff revision 6)
       
       
      Show all issues

      Unit test suite docstrings are in the form of: "Unit tests for module.path.to.thing." Also, trailing period.

    16. djblets/db/tests/test_query.py (Diff revision 6)
       
       
      Show all issues

      The docstrings should all mention prefix_q.

    17. 
        
    brennie
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/db/query.py
          djblets/db/tests/test_query.py
      
      
    2. 
        
    david
    1. 
        
    2. djblets/db/query.py (Diff revision 7)
       
       
      Show all issues

      Should be "Return a model instance"

    3. 
        
    brennie
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-0.10.x (86a4b74)