2015-10-07 16 views
8

nền

Hãy nói rằng tôi có một mẫu url với các thông số đó sẽ liên kết tôi đến một cái nhìn trong django:Django - nhận tên của thông số cần thiết để đảo ngược url

url(
    r'^things/(?P<thing_name>\w+)/features/(?P<feature_name>\w+)$', 
    views.thingFeature, 
    name='thing_feature' 
), 

Và cho phép nói rằng tôi có một thingfeature:

thing = Thing.objects.get(.....) 
feature = thing.feature_set.first() 

t_name = thing.name 
f_name = feature.name 

Bây giờ Django mang lại cho tôi khả năng tuyệt vời để có được một url mà mang lại cho tôi một trang dành riêng cho một tính năng cụ thể của một t cụ thể Hing. Tôi có thể làm điều đó như sau:

from django.core.urlresolvers import reverse 
url = reverse('thing_feature', thing_name=t_name, feature_name=f_name) 
# url == '/things/thing2/features/left-arm' 

Câu hỏi

Bây giờ tôi đã vấp vào một tình huống mà tôi cần phải giải quyết cụ thể. Tôi không tìm cách giải quyết - Tôi đang tìm cách giải quyết vấn đề sau:

Cho địa chỉ name của url, làm cách nào để có danh sách các tên đối số kwarg cần thiết để đảo ngược url đó?

Tôi đang tìm hàm get_kwarg_names_for_url. Nó hoạt động như vậy:

url_kwarg_names = get_kwarg_names_for_url('thing_feature') 
# url_kwarg_names == ['thing_name', 'feature_name'] 

url_kwarg_names bây giờ là danh sách của tất cả các từ khóa Tôi cần phải cung cấp cho reverse chức năng của Django để đảo ngược url tên "thing_feature".

Mọi trợ giúp đều được đánh giá cao!

Giải pháp

Dựa trên câu trả lời knbk của tôi đã có thể đưa ra các giải pháp sau đây:

def get_kwarg_names_for_url(url_name): 
    resolver = get_resolver(get_urlconf()) 
    reverse_data = resolver.reverse_dict[url_name] 

    pattern_list = reverse_data[0] 

    ''' 
    Need to specify the 1st pattern because url regexes can 
    potentially have multiple kwarg arrangments - this function does 
    not take this possibility into account. 
    ''' 
    first_pattern = pattern_list[0] 

    ''' 
    `first_pattern` is now of the form `(url_string, kwarg_list)` - 
    all we are interested in is the 2nd value. 
    ''' 
    return first_pattern[1] 
+0

Tôi vừa đi xuống một lỗ thỏ: đảo ngược url, khớp url với urlpattern, biên dịch regex urlpattern và kiểm tra 'groupindex' của regex ... Tôi đã bị thiếu thứ gì đó ở đây. – Monkpit

+1

Một vấn đề là bạn không thể đảo ngược url trước khi bạn đã biết tên tham số url bắt buộc - django sẽ tăng lỗi cho 'reverse ('thing_feature')' bởi vì nó thiếu các kwarg cần thiết! –

+0

Bạn có thể thử http://stackoverflow.com/a/1275601 này. Tôi đã thử bản thân mình ở đây và sử dụng '.items()' để thay thế, nó trả về một danh sách tốt các bộ dữ liệu có các kwarg. Bạn phải đi sâu hơn có vẻ là một khởi đầu tốt, tiếc là tôi sẽ về nhà ngay bây giờ và không thể đi sâu hơn. – Tiago

Trả lời

2

Tôi sẽ bắt đầu với một cảnh báo công bằng: điều này không thể sử dụng API công cộng. Trên hết, tôi đang tích cực làm việc để viết lại trình điều phối URL cho 1,10, vì vậy phương pháp này rất có thể sẽ bị phá vỡ vào thời điểm đó.

Trước tiên, bạn cần nhận được quyền RegexURLResolver.Nếu xem không phải là trong một không gian tên, bạn có thể sử dụng reverse_dict để có được một danh sách các khả năng, và trích xuất các kwargs:

def get_kwargs(view_name): 
    resolver = urlresolvers.get_resolver() 
    patterns = resolver.reverse_dict.getlist(view_name) 
    kwargs = [] 
    for possibility, pattern, defaults in patterns: 
     for result, params in possibility: 
      kwargs.append(params) 
    return kwargs 

Từ một tên xem có thể có nhiều mẫu với kwargs khác nhau (mặc dù bạn muốn để tránh điều đó cho sự tỉnh táo của bạn), điều này sẽ trả về một danh sách của mỗi tập hợp các kwarg có thể. Thông thường, các bộ khác nhau sẽ là các kwarg yêu cầu ở một bên và yêu cầu + kwarg tùy chọn ở phía bên kia.

Tôi chưa thử nghiệm điều này, nhưng nếu nó không hoạt động, bạn có thể đào xung quanh trong resolver.reverse_dict để tìm hiểu chi tiết cụ thể. Nó không được thiết kế chính xác với khả năng sử dụng trong tâm trí.

+0

Bạn là một kẻ man rợ. Mã của bạn không hoạt động khá trực tiếp, nhưng nó đã cho tôi nhiều thông tin hơn để làm cho nó hoạt động tốt. Tôi cũng không lo lắng về regexes url dẫn đến nhiều thỏa thuận kwarg. Cập nhật câu hỏi của tôi để phản ánh những gì làm việc cuối cùng. –

+0

p.s. Có vẻ như bạn là một trong những tác giả django? –

+0

@GershomMaes Tôi là một người đóng góp, không phải là một phần của đội ngũ cốt lõi mặc dù;) – knbk

0

Bạn sẽ có thể làm điều này với một resolve()

Từ Documents:

Một đối tượng ResolverMatch có thể được thẩm vấn để cung cấp thông tin về URL p attern phù hợp với một URL:

func, args, kwargs = resolve('/some/path/')

cụ thể để mã ví dụ của bạn:

url = reverse('thing_feature') 
func, args, kwargs = resolve(url) 
# args == ['thing_name', 'feature_name'] 
+0

Bạn không thể chuyển tên của url vào 'giải quyết'. – ozgur

+0

@ozgur được cập nhật dựa trên nhận xét của bạn. –

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