Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fixed #18974 -- Deprecated models.permalink decorator #377

Closed
wants to merge 4 commits into from

3 participants

@dstufft
Collaborator

This Pull Request deprecates the models.permalink decorator as per #18974.

It also includes updates to the documentation to take note of the deprecation and to point users towards using the reverse method instead.

@dstufft dstufft Fixed #18974 -- Deprecated models.permalink decorator
Added a PendingDeprecationWarning when calling models.permalink.
Additionally refactored the documentation to replace suggestions
of using the permalink decorator with the reverse function and
include it in the Deprecation timeline.
c83dd96
docs/ref/models/instances.txt
@@ -521,6 +525,8 @@ in ``get_absolute_url()`` and have all your other code call that one place.
The ``permalink`` decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. deprecated:: 1.5
+
The way we wrote ``get_absolute_url()`` above is a slightly violation of the
@akaariai Collaborator

This isn't true any more. The get_absolute_url() is non-DRY as it uses reverse()...

@dstufft Collaborator
dstufft added a note

Yea that's true. I didn't touch the permalink docs themselves other than adding the deprecated note. I wasn't sure if it would be better to leave them as is until it's removal, remove them completely, or just rewrite them to still document permalink but to mention that people should use reverse instead.

@dstufft Collaborator
dstufft added a note

To be more explicit, which way should the docs be changed?

@akaariai Collaborator

Well, that is a good question :) Maybe something along these lines:

deprecation reason: the permalink is deprecated, use get_absolute_url with reverse instead.

In early versions of Django there wasn't an easy way to use URLs defined in URLconf file inside get_absolute_url(). That meant you would need to define the URL both in URLConf and get_absolute_url(). Permalink was added to overcome this DRY principle violation. There is no reason to use permalink any more.

the actual docs for permalink here...

We should still have docs for the decorator until it is deprecated. The docs are a little verbose, but I don't see anything which must be reworded there...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@akaariai akaariai commented on the diff
docs/releases/1.5.txt
@@ -377,3 +377,10 @@ The markup contrib module has been deprecated and will follow an accelerated
deprecation schedule. Direct use of python markup libraries or 3rd party tag
libraries is preferred to Django maintaining this functionality in the
framework.
+
+
+``django.db.models.permalink``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :func:`~django.db.models.permalink` decorator has been deprecated. Use
@akaariai Collaborator

Do we need a more explicit guide on how to replace the permalink decorator? The answer might very well be no...

Maybe the permalink documentation should mention why it is deprecated. You can just use reverse inside the get_absolute_url, so you can always replace permalink by get_absolute_url which uses reverse.

@dstufft Collaborator
dstufft added a note

I don't think we need a more explicit guide. reverse() is documented and get_absolute_url() is documented, I think it should be fairly obvious what to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@dstufft
Collaborator

Updated the changes to the documentation to remove the line calling out the implementation of get_absolute_url as violating DRY, since it no longer was, and to explicitly mention the reason for both the inclusion of permalink and the reason for it's removal.

@timgraham
Owner

Based on the discussion in the ticket, doesn't look like formal deprecation is going to happen, but I've pulled the relevant docs from this into a patch and attached it to the ticket for review. Thanks!

@timgraham timgraham closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 18, 2012
  1. @dstufft

    Fixed #18974 -- Deprecated models.permalink decorator

    dstufft authored
    Added a PendingDeprecationWarning when calling models.permalink.
    Additionally refactored the documentation to replace suggestions
    of using the permalink decorator with the reverse function and
    include it in the Deprecation timeline.
  2. @dstufft
  3. @dstufft
  4. @dstufft
This page is out of date. Refresh to see the latest.
View
3  django/db/models/__init__.py
@@ -26,6 +26,9 @@ def permalink(func):
(viewname, viewargs)
(viewname, viewargs, viewkwargs)
"""
+ import warnings
+ warnings.warn('The permalink decorator has been deprecated. Use reverse instead.', PendingDeprecationWarning)
+
from django.core.urlresolvers import reverse
@wraps(func)
def inner(*args, **kwargs):
View
3  docs/internals/deprecation.txt
@@ -286,6 +286,9 @@ these changes.
* The ``mimetype`` argument to :class:`~django.http.HttpResponse` ``__init__``
will be removed (``content_type`` should be used instead).
+* The ``django.db.models.permalink`` decorator will be removed. The
+ ``django.core.urlresolvers.reverse`` function should be used instead.
+
2.0
---
View
25 docs/ref/models/instances.txt
@@ -478,9 +478,13 @@ For example::
return "/people/%i/" % self.id
(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>`,
-documented below, is usually the best approach and you should read that section
-before diving into code implementation.)
+write this kind of method. The :func:`reverse()<django.core.urlresolvers.reverse>`
+function is usually the best approach.)
+
+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
defines this method, the object-editing page will have a "View on site" link
@@ -521,11 +525,18 @@ in ``get_absolute_url()`` and have all your other code call that one place.
The ``permalink`` decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The way we wrote ``get_absolute_url()`` above is a slightly violation of the
-DRY principle: the URL for this object is defined both in the URLconf file and
-in the model.
+.. deprecated:: 1.5
+
+The ``permalink`` decorator has been deprecated and you should use
+:func:`reverse()<django.core.urlresolvers.reverse>` in the body of your
+``get_absolute_url`` method instead.
-You can decouple your models from the URLconf using the ``permalink`` decorator:
+In early versions of Django there wasn't an easy way to use URLs defined in
+URLconf file inside get_absolute_url(). That meant you would need to define the
+URL both in URLConf and get_absolute_url(). The ``permalink`` decorator was added
+to overcome this DRY principle violation. However since the inclusion of
+:func:`reverse()<django.core.urlresolvers.reverse>` there is no reason to use
+``permalink`` any more.
.. function:: permalink()
View
8 docs/ref/unicode.txt
@@ -262,11 +262,11 @@ Taking care in ``get_absolute_url()``
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
-way that is suitable for a URL. The ``django.db.models.permalink()`` decorator
-handles this for you automatically.
+way that is suitable for a URL. The ``django.core.urlresolvers.reverse()``
+function handles this for you automatically.
-If you're constructing a URL manually (i.e., *not* using the ``permalink()``
-decorator), you'll need to take care of the encoding yourself. In this case,
+If you're constructing a URL manually (i.e., *not* using the ``reverse()``
+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
above_. For example::
View
7 docs/releases/1.5.txt
@@ -377,3 +377,10 @@ The markup contrib module has been deprecated and will follow an accelerated
deprecation schedule. Direct use of python markup libraries or 3rd party tag
libraries is preferred to Django maintaining this functionality in the
framework.
+
+
+``django.db.models.permalink``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :func:`~django.db.models.permalink` decorator has been deprecated. Use
@akaariai Collaborator

Do we need a more explicit guide on how to replace the permalink decorator? The answer might very well be no...

Maybe the permalink documentation should mention why it is deprecated. You can just use reverse inside the get_absolute_url, so you can always replace permalink by get_absolute_url which uses reverse.

@dstufft Collaborator
dstufft added a note

I don't think we need a more explicit guide. reverse() is documented and get_absolute_url() is documented, I think it should be fairly obvious what to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+:func:`~django.core.urlresolvers.reverse` instead.
View
27 docs/topics/http/urls.txt
@@ -688,7 +688,7 @@ view::
)
This is completely valid, but it leads to problems when you try to do reverse
-URL matching (through the ``permalink()`` decorator or the :ttag:`url` template
+URL matching (through the ``reverse()`` function or the :ttag:`url` template
tag). Continuing this example, if you wanted to retrieve the URL for the
``archive`` view, Django's reverse URL matcher would get confused, because *two*
URL patterns point at that view.
@@ -999,25 +999,16 @@ whether a view would raise a ``Http404`` error before redirecting to it::
return HttpResponseRedirect('/')
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()
-------------------
.. function:: get_script_prefix()
-Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
-:func:`~django.db.models.permalink` to define URLs within your application.
-However, if your application constructs part of the URL hierarchy itself, you
-may occasionally need to generate URLs. In that case, you need to be able to
-find the base URL of the Django project within its Web server
-(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
-you). In that case, you can call ``get_script_prefix()``, which will return the
-script prefix portion of the URL for your Django project. If your Django
-project is at the root of its Web server, this is always ``"/"``.
+Normally, you should always use :func:`~django.core.urlresolvers.reverse` to
+define URLs within your application. However, if your application constructs
+part of the URL hierarchy itself, you may occasionally need to generate URLs.
+In that case, you need to be able to find the base URL of the Django project
+within its Web server (normally, :func:`~django.core.urlresolvers.reverse` takes
+care of this for you). In that case, you can call ``get_script_prefix()``, which
+will return the script prefix portion of the URL for your Django project. If
+your Django project is at the root of its Web server, this is always ``"/"``.
View
4 tests/regressiontests/generic_views/models.py
@@ -1,3 +1,4 @@
+from django.core.urlresolvers import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@@ -14,9 +15,8 @@ class Meta:
def __str__(self):
return self.name
- @models.permalink
def get_absolute_url(self):
- return ('artist_detail', (), {'pk': self.id})
+ return reverse('artist_detail', kwargs={'pk': self.id})
@python_2_unicode_compatible
class Author(models.Model):
Something went wrong with that request. Please try again.