2012-01-19 33 views
9

Tôi mới dùng python và django và tôi có câu hỏi liên quan đến chức năng chuyển hướng.Chuyển hướng Django với kwarg

Đây là phiên bản đã giảm của tệp views.py của tôi.

def page_index(request, error_message=''): 
    print error_message 

def add_page(request): 
    return redirect('page_index') # this work fine 
    return redirect('page_index', error_message='test') # this does not work 

Và đây là một phiên bản ngắn của urls.py tôi

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', {'error_message': 't'}, name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 

Khi tôi cố gắng chuyển hướng đến PAGE_INDEX mà không có sự tranh cãi từ khóa tất cả mọi thứ hoạt động tốt, nhưng khi tôi sử dụng kwag tôi nhận được lỗi sau thông điệp:

NoReverseMatch tại/trang/thêm/

Xếp cho 'PAGE_INDEX' với các đối số '()' một Không tìm thấy đối số từ khóa '{' error_message ':' test '}'.

Tôi đang làm gì sai?

Trả lời

10

Câu trả lời ngắn: Không có vị trí nào trong lược đồ url của bạn cho từ khóa 'error_message'.

Câu trả lời dài hơn:

Hàm redirect() đang gọi ngược lại() để tạo URL; nó sẽ gửi trình duyệt của người dùng đến URL đó bằng cách trả về phản hồi HTTP có mã trạng thái chuyển hướng 302 và url mới. Bất kỳ đối số từ khóa nào mà bạn cung cấp để đảo ngược() được cho là kết thúc như một phần của url - đó là cách chúng được truyền đạt đến người dùng.

Trong trường hợp của bạn, tuy nhiên, url cho 'page_index` chỉ được xác định là'^$ '- đây là url gốc, trông giống như' http://yoursite.com/ 'trong trình duyệt.

Nếu bạn muốn có thể phát hành chuyển hướng chứa thông tin khác, bạn sẽ cần xác định địa điểm cho nó trong url hoặc thêm địa điểm theo cách khác.

Hai Ba cách là khá phổ biến cho việc này:

  1. Sử dụng một tham số truy vấn - điều này sẽ gửi thông điệp tới khách hàng một cách rõ ràng; nếu bạn không cẩn thận, mọi người có thể tạo các url để làm cho trang chỉ mục của bạn nói bất cứ điều gì họ muốn.

    return redirect(reverse('page-index')+"?error_message=test")) 
    
  2. Stash tin nhắn trong phiên và kéo nó ra khi tải trang tiếp theo - điều này đòi hỏi bạn phải có phiên cấu hình, và theo dõi tất cả mọi thứ ở phía máy chủ, chứ không phải dựa vào khách hàng để gửi lại cho bạn những thông báo lỗi:

    def add_page(request): 
        request.session['error_message'] = 'test' 
        return redirect('page-index') 
    
    def page_index(request): 
        print request.session.get('error_message','') 
    
  3. Sử dụng khuôn khổ bài viết này - điều này được ưa thích hơn các thuộc tính phiên ad-hoc, miễn là bạn không cần phải quá nhiều 'loại' thông điệp trên cùng một trang.Nếu tất cả các bạn có một không gian trong mẫu của bạn cho thông báo lỗi, mặc dù, thì đây là thực sự dễ dàng:

    from django.contrib.messages import error 
    
    def add_page(request): 
        error(request, 'test') 
        return redirect('page-index') 
    

    Và sau đó trong mẫu cơ sở của bạn, có một khối giống như một nơi nào đó (có thể là phức tạp hơn này; theo kiểu , thậm chí):

    {% for message in messages %} 
        <p>{{ message }}</p> 
    {% endfor %} 
    

trong cả mọi trường hợp, tuy nhiên, bạn có thể loại bỏ các đối số từ urls.py của bạn - thông điệp riêng của mình sẽ không phải là một phần của các thành phần đường dẫn của URL.

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 
+0

là có một cách để gọi một cái nhìn với thông tin thats không phải trong url? – Justus1

+0

Có, bạn làm điều đó bằng Python - chỉ cần thực hiện 'return page_index (error_message = 'test')' từ khung nhìn add_page của bạn. –

+1

nhưng nếu bạn làm điều đó thì url không thay đổi, bạn đã trả lại nội dung của một chế độ xem khác (page_index) vào chế độ xem hiện tại (add_page) có vẻ như là một mẫu xấu đối với tôi. Ngoài ra, thay vì tung giải pháp nhắn tin dựa trên phiên của riêng bạn, tôi khuyên bạn nên sử dụng [khung thông điệp] tích hợp của Django (https://docs.djangoproject.com/en/1).3/ref/contrib/messages /) – Anentropic

0

redirect phải chuyển hướng đến url thực (đó là chuyển hướng HTTP, không chỉ là cuộc gọi Python).

Không có phân đoạn 'error_message' trong url của bạn, mặc dù bạn đã thiết lập nó để mặc định chế độ xem chức năng được gọi với error_message làm kwarg.

Vì đây là trang chỉ mục của bạn và bạn có thể không muốn thêm phân đoạn đường dẫn bổ sung vào url, bạn có thể hack nó lên bằng cách sử dụng GET vars. ví dụ

def page_index(request): 
    if 'error_message' in request.GET: 
     print request.GET['error_message'] 

from django.core.urlresolvers import reverse 

def add_page(request): 
    return redirect('%s?error_message=test' % reverse('page_index')) 

urlpatterns = patterns(
    'x.views', 
    url(r'^$', 'page_index', name='page_index'), 
    url(r'^add/$', 'add_page', name='add_page'), 
) 

Cập nhật:

Suy nghĩ về vấn đề này như tôi đi bộ về nhà, mặc dù câu hỏi của bạn là về chuyển hướng và kwargs vv, cho là lựa chọn tốt hơn ở đây sẽ được sử dụng Django messages framework và rời error_message hoàn toàn ra khỏi kwargs tầm nhìn của bạn, GET biến vv

ví dụ

from django.contrib import messages 

def add_page(request): 
    messages.add_message(request, messages.ERROR, 'test') 
    return redirect('page_index') 

Điều này cũng tránh mọi người có thể tạo các url với thông báo lỗi được tạo riêng của chúng trong đó, điều này có thể là một nguy cơ bảo mật.

2

Bạn có thể hoặc là tạo ra một mẫu url tên cho mỗi thông báo lỗi, và vượt qua nó trong dict args, như thế này:

url(r'^$', 'page_index', {'error_message': 'test'}, name='test_page_index'), 

hoặc nếu bạn sẵn sàng đưa các thông báo lỗi trong url thực tế bạn có thể lựa chọn cho việc này:

url(r'(?P"<"error_message">"\w+)/^$', 'page_index', name='page_index'), 

(hãy lấy "" xung quanh "<" và ">", phải đặt chúng trong dấu ngoặc hoặc họ sẽ được loại trừ hình thức câu trả lời, tôi đoán tất cả những gì trông giống như một các thẻ html được lọc ra)

và trong giao diện:

return redirect(reverse('page_index', args=['test'])) 
Các vấn đề liên quan