Fixed #18974 - Warned against using models.permalink
Thanks dstufft for the draft patch.
This commit is contained in:
parent
891c530624
commit
0e3690d230
|
@ -482,9 +482,13 @@ For example::
|
||||||
return "/people/%i/" % self.id
|
return "/people/%i/" % self.id
|
||||||
|
|
||||||
(Whilst this code is correct and simple, it may not be the most portable way to
|
(Whilst this code is correct and simple, it may not be the most portable way to
|
||||||
write this kind of method. The :func:`permalink() decorator <permalink>`,
|
write this kind of method. The :func:`~django.core.urlresolvers.reverse`
|
||||||
documented below, is usually the best approach and you should read that section
|
function is usually the best approach.)
|
||||||
before diving into code implementation.)
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('people.views.details', args=[str(self.id)])
|
||||||
|
|
||||||
One place Django uses ``get_absolute_url()`` is in the admin app. If an object
|
One place Django uses ``get_absolute_url()`` is in the admin app. If an object
|
||||||
defines this method, the object-editing page will have a "View on site" link
|
defines this method, the object-editing page will have a "View on site" link
|
||||||
|
@ -529,11 +533,19 @@ in ``get_absolute_url()`` and have all your other code call that one place.
|
||||||
The ``permalink`` decorator
|
The ``permalink`` decorator
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The way we wrote ``get_absolute_url()`` above is a slightly violation of the
|
.. warning::
|
||||||
DRY principle: the URL for this object is defined both in the URLconf file and
|
|
||||||
in the model.
|
|
||||||
|
|
||||||
You can decouple your models from the URLconf using the ``permalink`` decorator:
|
The ``permalink`` decorator is no longer recommended. You should use
|
||||||
|
:func:`~django.core.urlresolvers.reverse` in the body of your
|
||||||
|
``get_absolute_url`` method instead.
|
||||||
|
|
||||||
|
In early versions of Django, there wasn't an easy way to use URLs defined in
|
||||||
|
URLconf file inside :meth:`~django.db.models.Model.get_absolute_url`. That
|
||||||
|
meant you would need to define the URL both in URLConf and
|
||||||
|
:meth:`~django.db.models.Model.get_absolute_url`. The ``permalink`` decorator
|
||||||
|
was added to overcome this DRY principle violation. However, since the
|
||||||
|
introduction of :func:`~django.core.urlresolvers.reverse` there is no
|
||||||
|
reason to use ``permalink`` any more.
|
||||||
|
|
||||||
.. function:: permalink()
|
.. function:: permalink()
|
||||||
|
|
||||||
|
@ -544,14 +556,14 @@ correct URL, with all parameters substituted in the correct positions.
|
||||||
|
|
||||||
The ``permalink`` decorator is a Python-level equivalent to the :ttag:`url`
|
The ``permalink`` decorator is a Python-level equivalent to the :ttag:`url`
|
||||||
template tag and a high-level wrapper for the
|
template tag and a high-level wrapper for the
|
||||||
:func:`django.core.urlresolvers.reverse()` function.
|
:func:`~django.core.urlresolvers.reverse` function.
|
||||||
|
|
||||||
An example should make it clear how to use ``permalink()``. Suppose your URLconf
|
An example should make it clear how to use ``permalink()``. Suppose your URLconf
|
||||||
contains a line such as::
|
contains a line such as::
|
||||||
|
|
||||||
(r'^people/(\d+)/$', 'people.views.details'),
|
(r'^people/(\d+)/$', 'people.views.details'),
|
||||||
|
|
||||||
...your model could have a :meth:`~django.db.models.Model.get_absolute_url()`
|
...your model could have a :meth:`~django.db.models.Model.get_absolute_url`
|
||||||
method that looked like this::
|
method that looked like this::
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
|
@ -262,11 +262,11 @@ Taking care in ``get_absolute_url()``
|
||||||
|
|
||||||
URLs can only contain ASCII characters. If you're constructing a URL from
|
URLs can only contain ASCII characters. If you're constructing a URL from
|
||||||
pieces of data that might be non-ASCII, be careful to encode the results in a
|
pieces of data that might be non-ASCII, be careful to encode the results in a
|
||||||
way that is suitable for a URL. The ``django.db.models.permalink()`` decorator
|
way that is suitable for a URL. The :func:`~django.core.urlresolvers.reverse`
|
||||||
handles this for you automatically.
|
function handles this for you automatically.
|
||||||
|
|
||||||
If you're constructing a URL manually (i.e., *not* using the ``permalink()``
|
If you're constructing a URL manually (i.e., *not* using the ``reverse()``
|
||||||
decorator), you'll need to take care of the encoding yourself. In this case,
|
function), you'll need to take care of the encoding yourself. In this case,
|
||||||
use the ``iri_to_uri()`` and ``urlquote()`` functions that were documented
|
use the ``iri_to_uri()`` and ``urlquote()`` functions that were documented
|
||||||
above_. For example::
|
above_. For example::
|
||||||
|
|
||||||
|
|
|
@ -178,25 +178,17 @@ whether a view would raise a ``Http404`` error before redirecting to it::
|
||||||
return HttpResponseRedirect('/')
|
return HttpResponseRedirect('/')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
permalink()
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The :func:`~django.db.models.permalink` decorator is useful for writing short
|
|
||||||
methods that return a full URL path. For example, a model's
|
|
||||||
``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more.
|
|
||||||
|
|
||||||
get_script_prefix()
|
get_script_prefix()
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
.. function:: get_script_prefix()
|
.. function:: get_script_prefix()
|
||||||
|
|
||||||
Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
|
Normally, you should always use :func:`~django.core.urlresolvers.reverse` to
|
||||||
:func:`~django.db.models.permalink` to define URLs within your application.
|
define URLs within your application. However, if your application constructs
|
||||||
However, if your application constructs part of the URL hierarchy itself, you
|
part of the URL hierarchy itself, you may occasionally need to generate URLs.
|
||||||
may occasionally need to generate URLs. In that case, you need to be able to
|
In that case, you need to be able to find the base URL of the Django project
|
||||||
find the base URL of the Django project within its Web server
|
within its Web server (normally, :func:`~django.core.urlresolvers.reverse`
|
||||||
(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
|
takes care of this for you). In that case, you can call
|
||||||
you). In that case, you can call ``get_script_prefix()``, which will return the
|
``get_script_prefix()``, which will return the script prefix portion of the URL
|
||||||
script prefix portion of the URL for your Django project. If your Django
|
for your Django project. If your Django project is at the root of its web
|
||||||
project is at the root of its Web server, this is always ``"/"``.
|
server, this is always ``"/"``.
|
||||||
|
|
|
@ -552,12 +552,11 @@ layers where URLs are needed:
|
||||||
|
|
||||||
* In templates: Using the :ttag:`url` template tag.
|
* In templates: Using the :ttag:`url` template tag.
|
||||||
|
|
||||||
* In Python code: Using the :func:`django.core.urlresolvers.reverse()`
|
* In Python code: Using the :func:`django.core.urlresolvers.reverse`
|
||||||
function.
|
function.
|
||||||
|
|
||||||
* In higher level code related to handling of URLs of Django model instances:
|
* In higher level code related to handling of URLs of Django model instances:
|
||||||
The :meth:`django.db.models.Model.get_absolute_url()` method and the
|
The :meth:`~django.db.models.Model.get_absolute_url` method.
|
||||||
:func:`django.db.models.permalink` decorator.
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -622,10 +621,10 @@ view::
|
||||||
)
|
)
|
||||||
|
|
||||||
This is completely valid, but it leads to problems when you try to do reverse
|
This is completely valid, but it leads to problems when you try to do reverse
|
||||||
URL matching (through the :func:`~django.db.models.permalink` decorator or the
|
URL matching (through the :func:`~django.core.urlresolvers.reverse` function
|
||||||
:ttag:`url` template tag). Continuing this example, if you wanted to retrieve
|
or the :ttag:`url` template tag). Continuing this example, if you wanted to
|
||||||
the URL for the ``archive`` view, Django's reverse URL matcher would get
|
retrieve the URL for the ``archive`` view, Django's reverse URL matcher would
|
||||||
confused, because *two* URL patterns point at that view.
|
get confused, because *two* URL patterns point at that view.
|
||||||
|
|
||||||
To solve this problem, Django supports **named URL patterns**. That is, you can
|
To solve this problem, Django supports **named URL patterns**. That is, you can
|
||||||
give a name to a URL pattern in order to distinguish it from other patterns
|
give a name to a URL pattern in order to distinguish it from other patterns
|
||||||
|
@ -724,7 +723,7 @@ the fully qualified name into parts, and then tries the following lookup:
|
||||||
render a template.
|
render a template.
|
||||||
|
|
||||||
The current application can also be specified manually as an argument
|
The current application can also be specified manually as an argument
|
||||||
to the :func:`django.core.urlresolvers.reverse()` function.
|
to the :func:`django.core.urlresolvers.reverse` function.
|
||||||
|
|
||||||
3. If there is no current application. Django looks for a default
|
3. If there is no current application. Django looks for a default
|
||||||
application instance. The default application instance is the instance
|
application instance. The default application instance is the instance
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
|
||||||
|
@ -14,9 +15,8 @@ class Artist(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
@models.permalink
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return ('artist_detail', (), {'pk': self.id})
|
return reverse('artist_detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Author(models.Model):
|
class Author(models.Model):
|
||||||
|
|
Loading…
Reference in New Issue