2009-03-18 53 views
13

Giả sử tôi có URLconf như dưới đây và 'foo''bar' là các giá trị hợp lệ cho page_slug.Đảo ngược URL Django Với Tùy chọn Bổ sung

urlpatterns = patterns('', 
    (r'^page/(?P<page_slug>.*)/', 'myapp.views.someview'), 
) 

Sau đó, tôi có thể tạo lại URL bằng cách sử dụng bên dưới, phải không?

>>> from django.core.urlresolvers import reverse 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'foo'}) 
'/page/foo/' 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'bar'}) 
'/page/bar/' 

Nhưng điều gì sẽ xảy ra nếu tôi thay đổi cấu hình URL của mình?

urlpatterns = patterns('', 
    (r'^foo-direct/', 'myapp.views.someview', {'page_slug': 'foo'}), 
    (r'^my-bar-page/', 'myapp.views.someview', {'page_slug': 'bar'}), 
) 

tôi mong đợi kết quả này:

>>> from django.core.urlresolvers import reverse 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'foo'}) 
'/foo-direct/' 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'bar'}) 
'/my-bar-page/' 

Tuy nhiên, điều này ném một ngoại lệ NoReverseMatch. Tôi nghi ngờ tôi đang cố gắng làm điều gì đó không thể. Bất kỳ đề xuất nào về cách thức an toàn hơn để hoàn thành những gì tôi muốn?

URL được đặt tên không phải là một tùy chọn, vì tôi không muốn các ứng dụng khác liên kết với những ứng dụng này cần biết về chi tiết cụ thể của cấu trúc URL (đóng gói và tất cả).

+0

Ý anh là gì bởi "không làm việc"? Thông báo lỗi? Nếu có thì sao? –

+0

Nó ném một ngoại lệ 'NoReverseMatch'. –

+0

Vui lòng cập nhật câu hỏi bằng các sự kiện mới - không thêm thông tin hữu ích làm nhận xét. –

Trả lời

7

Đây là những gì chúng tôi làm.

urls.py có các mẫu như

url(r'^(?P<datarealm>.*?)/json/someClass/(?P<object_id>.*?)/$', 'json_someClass_resource',), 

views.py này như các cuộc gọi ngược như thế này

object = SomeModel.objects.get(...) 
    url= reverse('json_someClass_resource', kwargs={'object_id':object.id,'datarealm':object.datarealm.name}) 
+0

Tôi không nghĩ rằng sẽ giúp với vấn đề va chạm tên. –

+0

Tôi ban đầu đã bỏ phiếu bạn vì những gì David nói, nhưng có vẻ như bạn thực sự trả lời câu hỏi của Justin. Tôi vẫn nghĩ rằng câu trả lời của David là câu trả lời "tốt hơn", nhưng bạn là một khả năng. – Tyson

+0

Có lẽ tôi không hiểu làm thế nào điều này áp dụng cho các bên trên đọc đầu tiên. Tôi đoán nó có vẻ như nó có thể làm việc ... nhưng chỉ với chi phí đặt một tham chiếu đến một tên url ở cấp độ mô hình. Nếu object_1.datarealm.name = 'foo-direct' điều này sẽ hoạt động, nếu object_1.datarealm.name = 'foo', điều này sẽ không hoạt động. –

4

url Đặt tên phải là một lựa chọn. trường hợp của bạn được nhấn mạnh trong các tài liệu tham khảo Django:

http://docs.djangoproject.com/en/dev/topics/http/urls/?from=olddocs#id2

Tôi không chắc chắn các nhà thiết kế lại công việc xung quanh khác; họ mong đợi các url được đặt tên để che giấu nó.

Tôi có thể giải thích về việc đóng gói không? Cảm ơn. Có hai lý do chính:

  1. trừu tượng - không ai muốn để xem chi tiết
  2. An ninh - không ai nên xem chi tiết

Đối với 1, bạn có thể nhận được một số tiền phong phú của mileage ra khỏi nó trong python, và Django là một ví dụ tuyệt vời. Đối với 2, đó là một ngôn ngữ thông dịch. Hoặc bạn đang chạy nó, nơi nó được viết, hoặc bạn đang vận chuyển ra các tập tin .pyc biên dịch. Nếu đó thực sự là những gì bạn đang làm, hãy biên dịch url.

Cuối cùng, dường như gói gọn để cho các ứng dụng khác biết về các chức năng hơn cấu trúc url. Nhưng nếu bạn thực sự không đồng ý, tôi nghĩ bạn sẽ phải tự mình thực hiện một phương thức đảo ngược linh hoạt hơn.

+0

Đồng ý; việc xuất các URL được đặt tên dưới dạng API cũng giống như "được đóng gói" khi xuất tên hàm chế độ xem. –

+1

# 2 - Bảo mật thông qua sự tối tăm? :( – monokrome

+0

Tôi nghĩ rằng liên kết đã lỗi thời. Bạn muốn liên kết phần nào? –

19

Bạn nên thử đặt tên cho urlconfs của mình. Ví dụ:

urlpatterns = patterns('', 
    url(r'^foo-direct/', 'myapp.views.someview', {'page_slug': 'foo'}, name='foo-direct'), 
    url(r'^my-bar-page/', 'myapp.views.someview', {'page_slug': 'bar'}, name='bar-page'), 
) 

Sau đó, chỉ cần chỉnh sửa số lần hoàn lại và bạn sẽ làm cho nó hoạt động.Thông tin

>>> from django.core.urlresolvers import reverse 
>>> reverse('foo-direct', kwargs={'page_slug': 'foo'}) 
'/foo-direct/' 
>>> reverse('bar-page', kwargs={'page_slug': 'bar'}) 
'/my-bar-page/' 

thêm tại: Django Docs

+0

Chính xác điều này sẽ giúp ích cho url như thế nào trong câu hỏi: (r '^ page/(? P . *)/',' myapp.views.someview '),? – Rexford

Các vấn đề liên quan