Sử dụng {% url ??? %} trong các mẫu django


83

Tôi đã tìm kiếm rất nhiều trên google để tìm câu trả lời về cách sử dụng thẻ 'url' trong các mẫu chỉ để tìm thấy nhiều câu trả lời nói rằng 'Bạn chỉ cần chèn nó vào mẫu của mình và trỏ nó vào dạng xem bạn muốn url cho'. Chà, không có gì vui cho tôi :( Tôi đã thử mọi cách hoán vị có thể và đã dùng đến cách đăng ở đây như một phương sách cuối cùng.

Vì vậy, nó đây. Urls.py của tôi trông giống như sau:

from django.conf.urls.defaults import *
from login.views import *
from mainapp.views import *
import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^weclaim/', include('weclaim.foo.urls')),
    (r'^login/', login_view),
    (r'^logout/', logout_view),
    ('^$', main_view),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),
    #(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': '/home/arthur/Software/django/weclaim/templates/static'}),
    (r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
)

'Views.py' của tôi trong thư mục 'đăng nhập' của tôi trông giống như sau:

from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.contrib import auth

def login_view(request):
    if request.method == 'POST':
        uname = request.POST.get('username', '')
        psword = request.POST.get('password', '')
        user = auth.authenticate(username=uname, password=psword)
        # if the user logs in and is active
        if user is not None and user.is_active:
            auth.login(request, user)
            return render_to_response('main/main.html', {}, context_instance=RequestContext(request))
            #return redirect(main_view)
        else:
            return render_to_response('loginpage.html', {'box_width': '402', 'login_failed': '1',}, context_instance=RequestContext(request))
    else:
        return render_to_response('loginpage.html', {'box_width': '400',}, context_instance=RequestContext(request))

def logout_view(request):
    auth.logout(request)
    return render_to_response('loginpage.html', {'box_width': '402', 'logged_out': '1',}, context_instance=RequestContext(request))

và cuối cùng là main.html mà các điểm login_view trông giống như sau:

<html>
<body>
test! <a href="{% url logout_view %}">logout</a>
</body>
</html>

Vậy tại sao tôi luôn nhận được 'NoReverseMatch'?

* (có một lưu ý hơi khác là tôi phải sử dụng 'context_instance = RequestContext (request)' ở cuối tất cả các kết xuất để trả lời của tôi bởi vì nếu không nó sẽ không nhận ra {{MEDIA_URL}} trong các mẫu của tôi và tôi không thể tham chiếu bất kỳ tệp css hoặc js nào. Tôi không chắc tại sao lại như vậy. Có vẻ không đúng với tôi) *


1
Những gì bạn đang nói context_instance=RequestContext(request)là chính xác, điều này là cần thiết để cho phép mẫu truy cập vào các biến ngữ cảnh được cung cấp cho tất cả các mẫu. Điều này được thực hiện theo mặc định cho tất cả các chế độ xem chung, nhưng bạn cần tự thực hiện trong các chế độ xem tùy chỉnh của mình.
Marcus Whybrow

Có vẻ hơi lạ đối với tôi vì bạn sẽ truy cập các tệp css và js của mình mọi lúc từ các mẫu của bạn để giữ tính nhất quán trên trang web của bạn. Do đó, bạn không thể truy cập {{MEDIA_URL}} theo mặc định?
Robert Johnstone

1
Câu trả lời được chấp nhận ở đây là không còn giá trị
Dan Gayle

Thêm câu trả lời mới và sau đó tôi sẽ chấp nhận câu trả lời đó
Robert Johnstone

Câu trả lời:


54

Thay vì nhập logout_viewhàm, bạn nên cung cấp một chuỗi trongurls.py tệp :

Vì vậy, không (r'^login/', login_view),

nhưng (r'^login/', 'login.views.login_view'),

Đó là cách làm tiêu chuẩn. Sau đó, bạn có thể truy cập URL trong các mẫu của mình bằng cách sử dụng:

{% url login.views.login_view %}

2
vâng, chắc chắn sử dụng chuỗi. bằng cách này, bạn cũng có thể sử dụng các tiền tố và bạn không phải nhập tất cả các hàm chế độ xem của mình vào URLConf của mình.
Sri Raghavan

Tôi cũng đã thử điều này và nhận được thông báo 'Caught NoReverseMatch khi kết xuất: Đảo ngược cho' login.views.login_views 'với các đối số "()" và đối số từ khóa "{}" không tìm thấy. " một lần nữa :(
Robert Johnstone

Chờ đã ... Cào cái đó! Tôi đã đợi 15 phút, thử lại và nó hoạt động (yippeeee !!!). Đẹp 1. Câu hỏi tiếp theo. Nếu tôi chỉ có một trang web mà tôi đã thêm vào trang quản trị, thì làm cách nào để tôi có thể thêm trang này thành {% url ??? %}
Robert Johnstone

Có điều này là một hoại, nhưng thẻ URL vẫn cắn tôi trong năm 2015. Nó sẽ giúp đỡ nếu họ không tiếp tục thay đổi cú pháp:
Dave

6
Chỉ vì tôi đến đây từ google, tôi nên nói rằng đối với django 1.8+, việc chuyển chuỗi làm đối số chế độ xem không được dùng nữa và sẽ sớm bị xóa. Bạn thực sự nên vượt qua có thể gọi như trong bài đăng này.
user3599803

104

Câu trả lời được chọn đã lỗi thời và không có câu trả lời nào khác phù hợp với tôi (Django 1.6 và [apparantly] không có vùng tên đã đăng ký.)

Đối với Django 1.5 trở lên (từ tài liệu )

Cảnh báo Đừng quên đặt dấu ngoặc kép xung quanh đường dẫn hàm hoặc tên mẫu!

Với một URL được đặt tên, bạn có thể làm:

(r'^login/', login_view, name='login'),
...
<a href="{% url 'login' %}">logout</a>

Cũng dễ dàng nếu chế độ xem có tham số khác

def login(request, extra_param):
...
<a href="{% url 'login' 'some_string_containing_relevant_data' %}">login</a>

1
Vâng, tôi biết. Tôi đang sử dụng {% load url from future %}trong 1.4 vào lúc này. Vị trí tốt
Robert Johnstone

5
Đây nên được chọn làm câu trả lời. Việc sử dụng chuỗi cho url đối sánh ngược không được dùng trong các phiên bản django mới hơn.
Sumudu

44

Đảm bảo (django 1.5 trở lên) rằng bạn đặt tên url trong dấu ngoặc kép và nếu url của bạn có tham số thì chúng phải nằm ngoài dấu ngoặc kép (tôi đã mất hàng giờ để tìm ra sai lầm này!).

{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %}
<a href="{{ the_url }}"> link_name </a>

Tôi biết đây là một câu trả lời cũ, nhưng điều này thực sự đã giúp tôi. Tôi đang sử dụng django-norel, là một nhánh của Django 1.6, cũng phải gặp vấn đề này vì việc đóng gói tên url trong dấu ngoặc kép đã sửa lỗi TypeError mà tôi nhận được.
robobrobro

2
Sử dụng tài liệu chính xác cũng giúp ích, vì họ tiếp tục thay đổi cú pháp: {% url app_views.client client.id %}(không có dấu ngoặc kép) trong 1.4, {% url 'app_views.client' client.id %}(có dấu ngoặc kép) trong 1.5 -1.7 và {% url 'app-views-client' client.id %}(không có dấu gạch dưới hoặc dấu chấm, chỉ là dấu gạch ngang) trong 1.8.
Dave

Ôi Chúa ơi và tôi đã sớm lên kế hoạch nâng cấp lên 1.8.
Bogatyr

17

Các urlmẫu thẻ sẽ vượt qua các tham số như là một chuỗi và không phải là một tài liệu tham khảo chức năng để reverse(). Cách đơn giản nhất để làm cho điều này hoạt động là thêm một namevào dạng xem:

url(r'^/logout/' , logout_view, name='logout_view')

Tôi đã thử điều đó nhưng tôi nhận được 'cú pháp không hợp lệ (urls.py, dòng 14)' :(
Robert Johnstone

Điều thực sự kỳ lạ về điều này là nó (PyCharm - ứng dụng hay) sẽ không cho phép tôi sử dụng> name = 'logout_view' <như ở trên mà không đề xuất nhập thư viện (libxml2mod.name hoặc unicodedata.name hoặc twist.trial.runner. tên)
Robert Johnstone

Hàm reverse()được định nghĩa ở đâu?
CodyBugstein

Trong mẫu của bạn, sử dụng {% url 'logout_view'%} django.readthedocs.org/en/latest/intro/tutorial03.html
Juan Rojas

12

Tôi gặp phải vấn đề tương tự.

Những gì tôi tìm thấy từ tài liệu, chúng ta nên sử dụng namespace.

trong trường hợp của bạn {% url login:login_view %}


Sử dụng không gian tên nhiều hơn bây giờ một ngày. Làm cho URL dễ đọc hơn và họ thực sự có nghĩa là một cái gì đó cho bạn
Robert Johnstone

Bạn có thể bao gồm liên kết tài liệu xin vui lòng?
geoidesic

1

Đánh giá từ ví dụ của bạn, không nên {% url myproject.login.views.login_view %}và kết thúc câu chuyện? (thay thế myprojectbằng tên dự án thực tế của bạn)


Tương tự như ở trên 'Caught NoReverseMatch khi kết xuất: Đảo ngược cho' weclaim.login.views.login_views 'với các đối số' () 'và đối số từ khóa' {} 'không tìm thấy.' (Tôi cho rằng tên dự án của tôi giống với tên của thư mục gốc mà tất cả mã của tôi được lưu trữ trong đó)
Robert Johnstone
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.