Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

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

Closed
wants to merge 4 commits into from

3 participants

Donald Stufft Tim Graham Anssi Kääriäinen
Donald Stufft
Owner

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.

Donald Stufft 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.
521 525
 The ``permalink`` decorator
522 526
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
523 527
 
  528
+.. deprecated:: 1.5
  529
+
524 530
 The way we wrote ``get_absolute_url()`` above is a slightly violation of the
4
Anssi Kääriäinen Owner

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

Donald Stufft Owner

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.

Donald Stufft Owner

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

Anssi Kääriäinen Owner

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
Anssi Kääriäinen akaariai commented on the diff September 18, 2012
docs/releases/1.5.txt
@@ -377,3 +377,10 @@ The markup contrib module has been deprecated and will follow an accelerated
377 377
 deprecation schedule. Direct use of python markup libraries or 3rd party tag
378 378
 libraries is preferred to Django maintaining this functionality in the
379 379
 framework.
  380
+
  381
+
  382
+``django.db.models.permalink``
  383
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  384
+
  385
+The :func:`~django.db.models.permalink` decorator has been deprecated. Use
2
Anssi Kääriäinen Owner

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.

Donald Stufft Owner

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
Donald Stufft
Owner

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.

Tim Graham
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!

Tim Graham timgraham closed this November 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 4 unique commits by 1 author.

Sep 18, 2012
Donald Stufft 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
Donald Stufft Update the docs to better describe the permalink status 3b6bd4a
Donald Stufft Switch from using models.permalink to reverse 8314a4c
Donald Stufft Include a note in the deprecation timeline about permalink a86a201
This page is out of date. Refresh to see the latest.
3  django/db/models/__init__.py
@@ -26,6 +26,9 @@ def permalink(func):
26 26
         (viewname, viewargs)
27 27
         (viewname, viewargs, viewkwargs)
28 28
     """
  29
+    import warnings
  30
+    warnings.warn('The permalink decorator has been deprecated. Use reverse instead.', PendingDeprecationWarning)
  31
+
29 32
     from django.core.urlresolvers import reverse
30 33
     @wraps(func)
31 34
     def inner(*args, **kwargs):
3  docs/internals/deprecation.txt
@@ -286,6 +286,9 @@ these changes.
286 286
 * The ``mimetype`` argument to :class:`~django.http.HttpResponse` ``__init__``
287 287
   will be removed (``content_type`` should be used instead).
288 288
 
  289
+* The ``django.db.models.permalink`` decorator will be removed. The
  290
+  ``django.core.urlresolvers.reverse`` function should be used instead.
  291
+
289 292
 2.0
290 293
 ---
291 294
 
25  docs/ref/models/instances.txt
@@ -478,9 +478,13 @@ For example::
478 478
         return "/people/%i/" % self.id
479 479
 
480 480
 (Whilst this code is correct and simple, it may not be the most portable way to
481  
-write this kind of method. The :func:`permalink() decorator <permalink>`,
482  
-documented below, is usually the best approach and you should read that section
483  
-before diving into code implementation.)
  481
+write this kind of method. The :func:`reverse()<django.core.urlresolvers.reverse>`
  482
+function is usually the best approach.)
  483
+
  484
+For example::
  485
+
  486
+    def get_absolute_url(self):
  487
+        return reverse('people.views.details', args=[str(self.id)])
484 488
 
485 489
 One place Django uses ``get_absolute_url()`` is in the admin app. If an object
486 490
 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.
521 525
 The ``permalink`` decorator
522 526
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
523 527
 
524  
-The way we wrote ``get_absolute_url()`` above is a slightly violation of the
525  
-DRY principle: the URL for this object is defined both in the URLconf file and
526  
-in the model.
  528
+.. deprecated:: 1.5
  529
+
  530
+The ``permalink`` decorator has been deprecated and you should use
  531
+:func:`reverse()<django.core.urlresolvers.reverse>` in the body of your
  532
+``get_absolute_url`` method instead.
527 533
 
528  
-You can decouple your models from the URLconf using the ``permalink`` decorator:
  534
+In early versions of Django there wasn't an easy way to use URLs defined in
  535
+URLconf file inside get_absolute_url(). That meant you would need to define the
  536
+URL both in URLConf and get_absolute_url(). The ``permalink`` decorator was added
  537
+to overcome this DRY principle violation. However since the inclusion of
  538
+:func:`reverse()<django.core.urlresolvers.reverse>` there is no reason to use
  539
+``permalink`` any more.
529 540
 
530 541
 .. function:: permalink()
531 542
 
8  docs/ref/unicode.txt
@@ -262,11 +262,11 @@ Taking care in ``get_absolute_url()``
262 262
 
263 263
 URLs can only contain ASCII characters. If you're constructing a URL from
264 264
 pieces of data that might be non-ASCII, be careful to encode the results in a
265  
-way that is suitable for a URL. The ``django.db.models.permalink()`` decorator
266  
-handles this for you automatically.
  265
+way that is suitable for a URL. The ``django.core.urlresolvers.reverse()``
  266
+function handles this for you automatically.
267 267
 
268  
-If you're constructing a URL manually (i.e., *not* using the ``permalink()``
269  
-decorator), you'll need to take care of the encoding yourself. In this case,
  268
+If you're constructing a URL manually (i.e., *not* using the ``reverse()``
  269
+function), you'll need to take care of the encoding yourself. In this case,
270 270
 use the ``iri_to_uri()`` and ``urlquote()`` functions that were documented
271 271
 above_. For example::
272 272
 
7  docs/releases/1.5.txt
@@ -377,3 +377,10 @@ The markup contrib module has been deprecated and will follow an accelerated
377 377
 deprecation schedule. Direct use of python markup libraries or 3rd party tag
378 378
 libraries is preferred to Django maintaining this functionality in the
379 379
 framework.
  380
+
  381
+
  382
+``django.db.models.permalink``
  383
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  384
+
  385
+The :func:`~django.db.models.permalink` decorator has been deprecated. Use
  386
+:func:`~django.core.urlresolvers.reverse` instead.
27  docs/topics/http/urls.txt
@@ -688,7 +688,7 @@ view::
688 688
     )
689 689
 
690 690
 This is completely valid, but it leads to problems when you try to do reverse
691  
-URL matching (through the ``permalink()`` decorator or the :ttag:`url` template
  691
+URL matching (through the ``reverse()`` function or the :ttag:`url` template
692 692
 tag). Continuing this example, if you wanted to retrieve the URL for the
693 693
 ``archive`` view, Django's reverse URL matcher would get confused, because *two*
694 694
 URL patterns point at that view.
@@ -999,25 +999,16 @@ whether a view would raise a ``Http404`` error before redirecting to it::
999 999
             return HttpResponseRedirect('/')
1000 1000
         return response
1001 1001
 
1002  
-
1003  
-permalink()
1004  
------------
1005  
-
1006  
-The :func:`django.db.models.permalink` decorator is useful for writing short
1007  
-methods that return a full URL path. For example, a model's
1008  
-``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more.
1009  
-
1010 1002
 get_script_prefix()
1011 1003
 -------------------
1012 1004
 
1013 1005
 .. function:: get_script_prefix()
1014 1006
 
1015  
-Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
1016  
-:func:`~django.db.models.permalink` to define URLs within your application.
1017  
-However, if your application constructs part of the URL hierarchy itself, you
1018  
-may occasionally need to generate URLs. In that case, you need to be able to
1019  
-find the base URL of the Django project within its Web server
1020  
-(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
1021  
-you). In that case, you can call ``get_script_prefix()``, which will return the
1022  
-script prefix portion of the URL for your Django project. If your Django
1023  
-project is at the root of its Web server, this is always ``"/"``.
  1007
+Normally, you should always use :func:`~django.core.urlresolvers.reverse` to
  1008
+define URLs within your application. However, if your application constructs
  1009
+part of the URL hierarchy itself, you may occasionally need to generate URLs.
  1010
+In that case, you need to be able to find the base URL of the Django project
  1011
+within its Web server (normally, :func:`~django.core.urlresolvers.reverse` takes
  1012
+care of this for you). In that case, you can call ``get_script_prefix()``, which
  1013
+will return the script prefix portion of the URL for your Django project. If
  1014
+your Django project is at the root of its Web server, this is always ``"/"``.
4  tests/regressiontests/generic_views/models.py
... ...
@@ -1,3 +1,4 @@
  1
+from django.core.urlresolvers import reverse
1 2
 from django.db import models
2 3
 from django.utils.encoding import python_2_unicode_compatible
3 4
 
@@ -14,9 +15,8 @@ class Meta:
14 15
     def __str__(self):
15 16
         return self.name
16 17
 
17  
-    @models.permalink
18 18
     def get_absolute_url(self):
19  
-        return ('artist_detail', (), {'pk': self.id})
  19
+        return reverse('artist_detail', kwargs={'pk': self.id})
20 20
 
21 21
 @python_2_unicode_compatible
22 22
 class Author(models.Model):
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.