Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.5.X] Fixed #18974 - Warned against using models.permalink

Thanks dstufft for the draft patch.

Backport of 0e3690d from master
  • Loading branch information...
commit 42fa51c0027b1c40b897a0d51051a63962f95637 1 parent b9f9bc9
Tim Graham authored November 20, 2012
30  docs/ref/models/instances.txt
@@ -482,9 +482,13 @@ For example::
482 482
         return "/people/%i/" % self.id
483 483
 
484 484
 (Whilst this code is correct and simple, it may not be the most portable way to
485  
-write this kind of method. The :func:`permalink() decorator <permalink>`,
486  
-documented below, is usually the best approach and you should read that section
487  
-before diving into code implementation.)
  485
+write this kind of method. The :func:`~django.core.urlresolvers.reverse`
  486
+function is usually the best approach.)
  487
+
  488
+For example::
  489
+
  490
+    def get_absolute_url(self):
  491
+        return reverse('people.views.details', args=[str(self.id)])
488 492
 
489 493
 One place Django uses ``get_absolute_url()`` is in the admin app. If an object
490 494
 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.
529 533
 The ``permalink`` decorator
530 534
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
531 535
 
532  
-The way we wrote ``get_absolute_url()`` above is a slightly violation of the
533  
-DRY principle: the URL for this object is defined both in the URLconf file and
534  
-in the model.
  536
+.. warning::
  537
+
  538
+    The ``permalink`` decorator is no longer recommended. You should use
  539
+    :func:`~django.core.urlresolvers.reverse` in the body of your
  540
+    ``get_absolute_url`` method instead.
535 541
 
536  
-You can decouple your models from the URLconf using the ``permalink`` decorator:
  542
+In early versions of Django, there wasn't an easy way to use URLs defined in
  543
+URLconf file inside :meth:`~django.db.models.Model.get_absolute_url`. That
  544
+meant you would need to define the URL both in URLConf and
  545
+:meth:`~django.db.models.Model.get_absolute_url`. The ``permalink`` decorator
  546
+was added to overcome this DRY principle violation. However, since the
  547
+introduction of :func:`~django.core.urlresolvers.reverse` there is no
  548
+reason to use ``permalink`` any more.
537 549
 
538 550
 .. function:: permalink()
539 551
 
@@ -544,14 +556,14 @@ correct URL, with all parameters substituted in the correct positions.
544 556
 
545 557
 The ``permalink`` decorator is a Python-level equivalent to the :ttag:`url`
546 558
 template tag and a high-level wrapper for the
547  
-:func:`django.core.urlresolvers.reverse()` function.
  559
+:func:`~django.core.urlresolvers.reverse` function.
548 560
 
549 561
 An example should make it clear how to use ``permalink()``. Suppose your URLconf
550 562
 contains a line such as::
551 563
 
552 564
     (r'^people/(\d+)/$', 'people.views.details'),
553 565
 
554  
-...your model could have a :meth:`~django.db.models.Model.get_absolute_url()`
  566
+...your model could have a :meth:`~django.db.models.Model.get_absolute_url`
555 567
 method that looked like this::
556 568
 
557 569
     from django.db import models
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 :func:`~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
 
26  docs/ref/urlresolvers.txt
@@ -178,25 +178,17 @@ whether a view would raise a ``Http404`` error before redirecting to it::
178 178
             return HttpResponseRedirect('/')
179 179
         return response
180 180
 
181  
-
182  
-permalink()
183  
------------
184  
-
185  
-The :func:`~django.db.models.permalink` decorator is useful for writing short
186  
-methods that return a full URL path. For example, a model's
187  
-``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more.
188  
-
189 181
 get_script_prefix()
190 182
 -------------------
191 183
 
192 184
 .. function:: get_script_prefix()
193 185
 
194  
-Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
195  
-:func:`~django.db.models.permalink` to define URLs within your application.
196  
-However, if your application constructs part of the URL hierarchy itself, you
197  
-may occasionally need to generate URLs. In that case, you need to be able to
198  
-find the base URL of the Django project within its Web server
199  
-(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
200  
-you). In that case, you can call ``get_script_prefix()``, which will return the
201  
-script prefix portion of the URL for your Django project. If your Django
202  
-project is at the root of its Web server, this is always ``"/"``.
  186
+Normally, you should always use :func:`~django.core.urlresolvers.reverse` to
  187
+define URLs within your application. However, if your application constructs
  188
+part of the URL hierarchy itself, you may occasionally need to generate URLs.
  189
+In that case, you need to be able to find the base URL of the Django project
  190
+within its Web server (normally, :func:`~django.core.urlresolvers.reverse`
  191
+takes care of this for you). In that case, you can call
  192
+``get_script_prefix()``, which will return the script prefix portion of the URL
  193
+for your Django project. If your Django project is at the root of its web
  194
+server, this is always ``"/"``.
15  docs/topics/http/urls.txt
@@ -552,12 +552,11 @@ layers where URLs are needed:
552 552
 
553 553
 * In templates: Using the :ttag:`url` template tag.
554 554
 
555  
-* In Python code: Using the :func:`django.core.urlresolvers.reverse()`
  555
+* In Python code: Using the :func:`django.core.urlresolvers.reverse`
556 556
   function.
557 557
 
558 558
 * In higher level code related to handling of URLs of Django model instances:
559  
-  The :meth:`django.db.models.Model.get_absolute_url()` method and the
560  
-  :func:`django.db.models.permalink` decorator.
  559
+  The :meth:`~django.db.models.Model.get_absolute_url` method.
561 560
 
562 561
 Examples
563 562
 --------
@@ -622,10 +621,10 @@ view::
622 621
     )
623 622
 
624 623
 This is completely valid, but it leads to problems when you try to do reverse
625  
-URL matching (through the :func:`~django.db.models.permalink` decorator or the
626  
-:ttag:`url` template tag). Continuing this example, if you wanted to retrieve
627  
-the URL for the ``archive`` view, Django's reverse URL matcher would get
628  
-confused, because *two* URL patterns point at that view.
  624
+URL matching (through the :func:`~django.core.urlresolvers.reverse` function
  625
+or the :ttag:`url` template tag). Continuing this example, if you wanted to
  626
+retrieve the URL for the ``archive`` view, Django's reverse URL matcher would
  627
+get confused, because *two* URL patterns point at that view.
629 628
 
630 629
 To solve this problem, Django supports **named URL patterns**. That is, you can
631 630
 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:
724 723
    render a template.
725 724
 
726 725
    The current application can also be specified manually as an argument
727  
-   to the :func:`django.core.urlresolvers.reverse()` function.
  726
+   to the :func:`django.core.urlresolvers.reverse` function.
728 727
 
729 728
 3. If there is no current application. Django looks for a default
730 729
    application instance. The default application instance is the instance
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):

0 notes on commit 42fa51c

Please sign in to comment.
Something went wrong with that request. Please try again.