Skip to content

Commit

Permalink
Apply more changes for blacken-docs to pass, and once fixed apply bla…
Browse files Browse the repository at this point in the history
…cken-docs again.
  • Loading branch information
jvzammit committed Nov 23, 2022
1 parent f8013fa commit 7338749
Show file tree
Hide file tree
Showing 164 changed files with 6,363 additions and 3,171 deletions.
5 changes: 4 additions & 1 deletion docs/faq/models.txt
Expand Up @@ -36,9 +36,12 @@ same interface on each member of the ``connections`` dictionary:
>>> connections["my_db_alias"].queries

If you need to clear the query list manually at any point in your functions,
call ``reset_queries()``, like this::
call ``reset_queries()``, like this:

.. code-block:: python

from django.db import reset_queries

reset_queries()

Can I use Django with a preexisting database?
Expand Down
7 changes: 5 additions & 2 deletions docs/howto/auth-remote-user.txt
Expand Up @@ -77,12 +77,15 @@ regardless of ``AUTHENTICATION_BACKENDS``.

If your authentication mechanism uses a custom HTTP header and not
``REMOTE_USER``, you can subclass ``RemoteUserMiddleware`` and set the
``header`` attribute to the desired ``request.META`` key. For example::
``header`` attribute to the desired ``request.META`` key. For example:

.. code-block:: python

from django.contrib.auth.middleware import RemoteUserMiddleware


class CustomHeaderMiddleware(RemoteUserMiddleware):
header = 'HTTP_AUTHUSER'
header = "HTTP_AUTHUSER"

.. warning::

Expand Down
15 changes: 10 additions & 5 deletions docs/howto/csrf.txt
Expand Up @@ -200,11 +200,14 @@ However, if you use cache decorators on individual views, the CSRF middleware
will not yet have been able to set the Vary header or the CSRF cookie, and the
response will be cached without either one. In this case, on any views that
will require a CSRF token to be inserted you should use the
:func:`django.views.decorators.csrf.csrf_protect` decorator first::
:func:`django.views.decorators.csrf.csrf_protect` decorator first:

.. code-block:: python

from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import csrf_protect


@cache_page(60 * 15)
@csrf_protect
def my_view(request):
Expand Down Expand Up @@ -276,21 +279,23 @@ it for the rest of the time.

Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` for the whole
view function, and :func:`~django.views.decorators.csrf.csrf_protect` for the
path within it that needs protection. Example::
path within it that needs protection. Example:

.. code-block:: python

from django.views.decorators.csrf import csrf_exempt, csrf_protect


@csrf_exempt
def my_view(request):

@csrf_protect
def protected_path(request):
do_something()

if some_condition():
return protected_path(request)
return protected_path(request)
else:
do_something_else()
do_something_else()

Protecting a page that uses AJAX without an HTML form
-----------------------------------------------------
Expand Down
10 changes: 8 additions & 2 deletions docs/howto/custom-file-storage.txt
Expand Up @@ -9,19 +9,25 @@ on some remote system -- you can do so by defining a custom storage class.
You'll need to follow these steps:

#. Your custom storage system must be a subclass of
``django.core.files.storage.Storage``::
``django.core.files.storage.Storage``:

.. code-block:: python

from django.core.files.storage import Storage


class MyStorage(Storage):
...

#. Django must be able to instantiate your storage system without any arguments.
This means that any settings should be taken from ``django.conf.settings``::
This means that any settings should be taken from ``django.conf.settings``:

.. code-block:: python

from django.conf import settings
from django.core.files.storage import Storage


class MyStorage(Storage):
def __init__(self, option=None):
if not option:
Expand Down
94 changes: 62 additions & 32 deletions docs/howto/custom-lookups.txt
Expand Up @@ -13,7 +13,7 @@ A lookup example
================

Let's start with a small custom lookup. We will write a custom lookup ``ne``
which works opposite to ``exact``. ``Author.objects.filter(name__ne='Jack')``
which works opposite to ``exact``. ``Author.objects.filter(name__ne="Jack")``
will translate to the SQL:

.. code-block:: sql
Expand All @@ -24,34 +24,43 @@ This SQL is backend independent, so we don't need to worry about different
databases.

There are two steps to making this work. Firstly we need to implement the
lookup, then we need to tell Django about it::
lookup, then we need to tell Django about it:

.. code-block:: python

from django.db.models import Lookup


class NotEqual(Lookup):
lookup_name = 'ne'
lookup_name = "ne"

def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s <> %s' % (lhs, rhs), params
return "%s <> %s" % (lhs, rhs), params

To register the ``NotEqual`` lookup we will need to call ``register_lookup`` on
the field class we want the lookup to be available for. In this case, the lookup
makes sense on all ``Field`` subclasses, so we register it with ``Field``
directly::
directly:

.. code-block:: python

from django.db.models import Field

Field.register_lookup(NotEqual)

Lookup registration can also be done using a decorator pattern::
Lookup registration can also be done using a decorator pattern:

.. code-block:: python

from django.db.models import Field


@Field.register_lookup
class NotEqualLookup(Lookup):
# ...
...

We can now use ``foo__ne`` for any field ``foo``. You will need to ensure that
this registration happens before you try to create any querysets using it. You
Expand All @@ -76,7 +85,7 @@ A ``Lookup`` works against two values, ``lhs`` and ``rhs``, standing for
left-hand side and right-hand side. The left-hand side is usually a field
reference, but it can be anything implementing the :ref:`query expression API
<query-expression>`. The right-hand is the value given by the user. In the
example ``Author.objects.filter(name__ne='Jack')``, the left-hand side is a
example ``Author.objects.filter(name__ne="Jack")``, the left-hand side is a
reference to the ``name`` field of the ``Author`` model, and ``'Jack'`` is the
right-hand side.

Expand Down Expand Up @@ -111,17 +120,23 @@ or where it did not exceed a certain amount
and without duplicating functionality already in Django.

We will start by writing an ``AbsoluteValue`` transformer. This will use the SQL
function ``ABS()`` to transform the value before comparison::
function ``ABS()`` to transform the value before comparison:

.. code-block:: python

from django.db.models import Transform


class AbsoluteValue(Transform):
lookup_name = 'abs'
function = 'ABS'
lookup_name = "abs"
function = "ABS"

Next, let's register it for ``IntegerField``::
Next, let's register it for ``IntegerField``:

.. code-block:: python

from django.db.models import IntegerField

IntegerField.register_lookup(AbsoluteValue)

We can now run the queries we had before.
Expand All @@ -144,14 +159,14 @@ Note that in case there is no other lookup specified, Django interprets
``change__abs=27`` as ``change__abs__exact=27``.

This also allows the result to be used in ``ORDER BY`` and ``DISTINCT ON``
clauses. For example ``Experiment.objects.order_by('change__abs')`` generates:
clauses. For example ``Experiment.objects.order_by("change__abs")`` generates:

.. code-block:: sql

SELECT ... ORDER BY ABS("experiments"."change") ASC

And on databases that support distinct on fields (such as PostgreSQL),
``Experiment.objects.distinct('change__abs')`` generates:
``Experiment.objects.distinct("change__abs")`` generates:

.. code-block:: sql

Expand All @@ -163,13 +178,16 @@ this here as it didn't change, but supposing we were applying ``AbsoluteValue``
to some field which represents a more complex type (for example a point
relative to an origin, or a complex number) then we may have wanted to specify
that the transform returns a ``FloatField`` type for further lookups. This can
be done by adding an ``output_field`` attribute to the transform::
be done by adding an ``output_field`` attribute to the transform:

.. code-block:: python

from django.db.models import FloatField, Transform


class AbsoluteValue(Transform):
lookup_name = 'abs'
function = 'ABS'
lookup_name = "abs"
function = "ABS"

@property
def output_field(self):
Expand All @@ -193,18 +211,22 @@ the following SQL:

SELECT .. WHERE "experiments"."change" < 27 AND "experiments"."change" > -27

The implementation is::
The implementation is:

.. code-block:: python

from django.db.models import Lookup


class AbsoluteValueLessThan(Lookup):
lookup_name = 'lt'
lookup_name = "lt"

def as_sql(self, compiler, connection):
lhs, lhs_params = compiler.compile(self.lhs.lhs)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params + lhs_params + rhs_params
return '%s < %s AND %s > -%s' % (lhs, rhs, lhs, rhs), params
return "%s < %s AND %s > -%s" % (lhs, rhs, lhs, rhs), params


AbsoluteValue.register_lookup(AbsoluteValueLessThan)

Expand Down Expand Up @@ -248,18 +270,24 @@ transformations in a database-agnostic way.
We define an ``UpperCase`` transformer which uses the SQL function ``UPPER()`` to
transform the values before comparison. We define
:attr:`bilateral = True <django.db.models.Transform.bilateral>` to indicate that
this transformation should apply to both ``lhs`` and ``rhs``::
this transformation should apply to both ``lhs`` and ``rhs``:

.. code-block:: python

from django.db.models import Transform


class UpperCase(Transform):
lookup_name = 'upper'
function = 'UPPER'
lookup_name = "upper"
function = "UPPER"
bilateral = True

Next, let's register it::
Next, let's register it:

.. code-block:: python

from django.db.models import CharField, TextField

CharField.register_lookup(UpperCase)
TextField.register_lookup(UpperCase)

Expand Down Expand Up @@ -306,11 +334,13 @@ In some cases you may wish to dynamically change which ``Transform`` or
an example, you could have a field which stores coordinates or an arbitrary
dimension, and wish to allow a syntax like ``.filter(coords__x7=4)`` to return
the objects where the 7th coordinate has value 4. In order to do this, you
would override ``get_lookup`` with something like::
would override ``get_lookup`` with something like:

.. code-block:: python

class CoordinatesField(Field):
def get_lookup(self, lookup_name):
if lookup_name.startswith('x'):
if lookup_name.startswith("x"):
try:
dimension = int(lookup_name[1:])
except ValueError:
Expand All @@ -333,11 +363,11 @@ will look for a ``Lookup``. If there are multiple names, it will look for a
is not found, we look for a ``Transform`` and then the ``exact`` lookup on that
``Transform``. All call sequences always end with a ``Lookup``. To clarify:

- ``.filter(myfield__mylookup)`` will call ``myfield.get_lookup('mylookup')``.
- ``.filter(myfield__mylookup)`` will call ``myfield.get_lookup("mylookup")``.
- ``.filter(myfield__mytransform__mylookup)`` will call
``myfield.get_transform('mytransform')``, and then
``mytransform.get_lookup('mylookup')``.
``myfield.get_transform("mytransform")``, and then
``mytransform.get_lookup("mylookup")``.
- ``.filter(myfield__mytransform)`` will first call
``myfield.get_lookup('mytransform')``, which will fail, so it will fall back
to calling ``myfield.get_transform('mytransform')`` and then
``mytransform.get_lookup('exact')``.
``myfield.get_lookup("mytransform")``, which will fail, so it will fall back
to calling ``myfield.get_transform("mytransform")`` and then
``mytransform.get_lookup("exact")``.

0 comments on commit 7338749

Please sign in to comment.