Django kullanarak mevcut url adı nasıl alınır?


91

Mevcut url'ye göre dinamik olarak bir url oluşturmam gerekiyor. {% url %}Etiketi kullanmak bunu yapmanın en kolay yoludur, ancak yenisini dinamik olarak oluşturmak için mevcut url adına ihtiyacım var.

Geçerli görünüme götüren urlconf'a eklenen url adını nasıl alabilirim?

DÜZENLEME: URL'yi kullanarak manuel olarak elle işleyebileceğimi biliyorum, get_absolute_urlancak bir dersin parçası olduğu için bundan kaçınmayı tercih ederim ve url'leri oluşturmanın tek bir yolunu göstermek istiyorum.

Öğrenciler nasıl kullanılacağını biliyor {% url %}. Mevcut olana göre daha eksiksiz bir url oluşturmaları gerektiğinde bir sorunla karşı karşıya olduklarını biliyorlar. En kolay yol, {% url %}bazı varyasyonlarla tekrar kullanmaktır . Url adını verdiğimiz için, mevcut görünümü çağıran url'nin adını nasıl alacağımızı bilmemiz gerekir.

DÜZENLEME 2: başka bir kullanım durumu, temel şablonun parçalarını temel şablona göre farklı bir şekilde görüntülemektir. Bunu yapmanın başka yolları da var (CSS ve {% block%} kullanarak, ancak bazen, eğer görünüm adı bağlantıyla eşleşiyorsa, base.html'nin menü girişinin etiketini kaldırabilmek güzel.


6
Mevcut, mutlak url'yi bir şablon etiketi aracılığıyla çıkarmanın bir yolunu ararken bu soruyu bulmaya devam ettim ... Bunu da arıyorsanız, şu:{{ request.get_full_path }}
Dolph

Yanıtlar:


134

Bu özelliğin Django'nun ne kadar zamandır bir parçası olduğunu bilmiyorum, ancak aşağıdaki makalenin gösterdiği gibi, görünümde aşağıdaki gibi elde edilebilir:

   from django.core.urlresolvers import resolve
   current_url = resolve(request.path_info).url_name

Her şablonda buna ihtiyacınız varsa, bir şablon isteği yazmak uygun olabilir.

Düzenleme: YENİ DJANGO GÜNCELLEMESİNİ UYGULAMA

Mevcut Django güncellemesinin ardından:

Django 1.10 ( bağlantı )

django.core.urlresolversModülden içe aktarma , yeni konumu lehine kullanımdan kaldırıldı,django.urls

Django 2.0 ( bağlantı )

django.core.urlresolversModül, yeni konumuna lehine kaldırılır django.urls.

Dolayısıyla, yapmanın doğru yolu şudur:

from django.urls import resolve
current_url = resolve(request.path_info).url_name

Neden? Sorunuzu anladığım kadarıyla, önemli bir kısmı "url adını verdiğimizden, mevcut görünümü çağıran url'nin adını nasıl alacağımızı bilmemiz gerekiyor." ...
Lukas Bünger

1
Aslında lukas o gün huysuzdum ve cevabınızı tamamen keyfi bir şekilde reddettim. Özür dilerim çünkü bu aslında doğru cevap. daha kıskanç hale getirmek için onu düzenleyeceğim.
e-satis

8
resolve()bir sorgu dizesi geçirirseniz ve yalnızca bir 404 yükseltirseniz çözülemez get_full_path(). yolu ve sorgu dizesini döndürür. Kullanmanız gerekecek resolve(request.path_info).
Can Burak Çilingir

Ya currentçözülmesi gereken url değilse , ancak, örneğin bir kullanıcının yönlendireceği url ise? Bunu başarmanın daha genel bir yolu nedir? Conley Owens'ın cevabının bir ipucu var, ancak söz konusu tekerlek kaputun altındaki Django'da zaten mevcutsa tekerleği yeniden icat etmemeyi tercih ederim.
Hassan Baig

Bu, i18n_patterns ile çevrilebilir url'ler için işe yaramıyor gibi görünüyor
guival

110

Django 1.5'ten itibaren buna istek nesnesinden erişilebilir

current_url = request.resolver_match.url_name

Ad alanıyla birlikte url adını isterseniz

current_url = request.resolver_match.view_name

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match


Bunu bir bağlam işlemcisine koyduğumda işe yaradı, ancak bu garip hata konsolda gösterildi:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj

2
'Resolver_match' istek nesnesine yalnızca tüm istek ara yazılımlarını çağırdıktan sonra eklenir. Bu, url'lerin çözüldüğü zamandır. Böylece, yalnızca ara katman yazılımını görüntülemeden erişebilirsiniz. (ara yazılımın process_view işlevleri). İstek ara yazılım işlevlerinde kullanılamayacaktır. (ara yazılımın process_request işlevleri).
Bharathwaaj

.view_namead

29

Url kalıplarını ad alanı kullananlar için, isteğin ad alanlı url adıyla ilgilenebilirsiniz. Bu durumda, Django onu aradı view_name.

request.resolver_match.view_name

# return: <namespace>:<url name>

Teşekkürler, ama bu @ dariusz-niespodziany'nin önceki cevabının bir kopyası, değil mi? stackoverflow.com/a/31931833/1450294
Michael Scheper

5
urls.pyAd alanı yapmadıysanız, @ dariusz-niespodziany hemen reverse-able olur. Ancak ad alanı kullanıyorsanız, resolver_match.url_namedoğrudan reverse-able değildir . Bu nedenle ad alanını kendiniz eklemeniz gerekir. Yani, bunu kendiniz yapmak yerine, Django zaten .view_namebaşlatmayı ayarladı .
Yeo

16

Bu şu yollarla sağlanabilir:

    request.resolver_match.url_name

Django> 1.8


4

Sorunun açıklaması: "Bir görüşe göre, tam olarak böyle bir url şablonu olduğu varsayılarak, ona işaret eden bir url şablonunun adını nasıl elde edersiniz?"

Belirtilen nedenlerden dolayı bu arzu edilebilir: görünümün içinden, aynı görünüme bir url almanın KURU bir yolunu istiyoruz (kendi url şablon adımızı bilmek istemiyoruz).

Kısa cevap: Sınıfınıza öğretmek için yeterince basit değil, ancak bir veya iki saat içinde yapıp GitHub'a kusmanız eğlenceli olabilir.

Bunu gerçekten yapmak istiyorsanız, RegexURLResolver'ın alt sınıfına girmeniz ve görünüm ve anahtar kelime / değer çiftleri yerine eşleşen kalıbı (kalıp adını alabileceğiniz) döndürmek için çözümleme yöntemini değiştirmeniz gerekir. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

Ardından, desen adını almak ve bu değeri istekte bir yerde saklamak için bu alt sınıfı kullanan bir dekoratör veya belki de daha uygun bir ara yazılım yaratabilirsiniz, böylece görünümler onu kullanabilir.

Bunu gerçekten yapmak istiyorsan ve bir sorunla karşılaşırsan bana haber ver ve muhtemelen yardımcı olabilirim.

Sınıfınız için, onlara model adını görünümde veya şablonda sabit kodlamalarını isterim. Bunu yapmanın kabul edilebilir yolu olduğuna inanıyorum.

Güncelleme: Bunun hakkında ne kadar çok düşünürsem, bir görünümde bir urlpattern adı almaya çalışmaktan o kadar vazgeçerim. urlpattern parametreleri, gösterdikleri görünümün parametrelerinden oldukça bağımsızdır. Belirli bir url'yi göstermek istiyorsanız, sadece görünümün nasıl çalıştığını değil, url şablonunun nasıl çalıştığını bilmeniz gerekir. Url şablonunun nasıl çalıştığını bilmeniz gerekiyorsa, url şablonunun adını da bilmeniz gerekebilir.




1

Sorunuz biraz net değil, ancak http://docs.djangoproject.com/en/dev/topics/http/urls/ muhtemelen peşinde olduğunuz şeyle ilgili bir açıklama sağlayacaktır.

Django'nun istekleri nasıl işlediğini not etmek özellikle yararlıdır:

Bir kullanıcı Django destekli sitenizden bir sayfa istediğinde, bu, sistemin hangi Python kodunun çalıştırılacağını belirlemek için izlediği algoritmadır:

  1. Django, kullanılacak kök URLconf modülünü belirler. Normalde, bu ROOT_URLCONF ayarının değeridir, ancak gelen HttpRequest nesnesinin urlconf adında bir özniteliği varsa (ara yazılım istek işleme tarafından ayarlanmış), değeri ROOT_URLCONF ayarı yerine kullanılacaktır.
  2. Django, bu Python modülünü yükler ve değişken url şablonlarını arar. Bu, django.conf.urls.defaults.patterns () işlevi tarafından döndürülen formatta bir Python listesi olmalıdır.
  3. Django, sırayla her bir URL modelinde ilerler ve istenen URL ile eşleşen ilkinde durur.
  4. Normal ifadelerden biri eşleştiğinde, Django verilen görünümü içe aktarır ve çağırır, bu basit bir Python işlevi. Görünüm, ilk bağımsız değişkeni olarak bir HttpRequest'i ve normal ifadede kalan bağımsız değişkenler olarak yakalanan değerleri alır.

Tam yolun hemen peşindeyseniz, deneyebilirsiniz:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

Umarım bu yardımcı olur - URLconf modülünün nasıl kullanılacağını gösterir ve umarım sizi doğru yöne yönlendirmeye yardımcı olur.


Teşekkürler ama biliyorum :-) Yanlış anlaşılmayı önlemek için bazı açıklamalar ekledim.
e-satis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.