Bagaimana cara mendapatkan nama url saat ini menggunakan Django?

91

Saya harus membangun url secara dinamis sesuai dengan url saat ini. Menggunakan {% url %}tag adalah cara termudah untuk melakukannya, tetapi saya memerlukan nama url saat ini untuk membuat yang baru secara dinamis.

Bagaimana cara mendapatkan nama url yang dilampirkan ke urlconf yang mengarah ke tampilan saat ini?

EDIT: Saya tahu saya bisa secara manual membuat url menggunakan get_absolute_urltetapi saya lebih suka menghindarinya karena itu bagian dari kuliah dan saya ingin menunjukkan hanya satu cara untuk membangun url.

Para siswa tahu cara menggunakan {% url %}. Mereka tahu bahwa mereka menghadapi masalah ketika mereka harus membuat url yang lebih lengkap berdasarkan url saat ini. Cara termudah adalah menggunakannya {% url %}kembali, dengan beberapa variasi. Karena kita telah menamai url, kita perlu mengetahui bagaimana mendapatkan nama url yang disebut tampilan saat ini.

EDIT 2: kasus penggunaan lain adalah menampilkan bagian dari templat dasar secara berbeda sesuai dengan templat dasar. Ada cara lain untuk melakukannya (menggunakan CSS dan {% block%}, tapi kadang-kadang senang bisa menghapus tag dari entri menu base.html jika nama tampilan cocok dengan link.

e-satis
sumber
6
Saya terus menemukan pertanyaan ini saat mencari cara untuk menampilkan url absolut saat ini melalui tag templat ... jika Anda juga mencarinya, ini:{{ request.get_full_path }}
Dolph

Jawaban:

134

Saya tidak tahu berapa lama fitur ini telah menjadi bagian dari Django tetapi seperti yang diperlihatkan artikel berikut , ini dapat dicapai sebagai berikut dalam tampilan:

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

Jika Anda membutuhkannya di setiap template, menulis permintaan template bisa jadi sesuai.

Sunting: MENERAPKAN PEMBARUAN DJANGO BARU

Mengikuti pembaruan Django saat ini:

Django 1.10 ( tautan )

Mengimpor dari django.core.urlresolversmodul tidak digunakan lagi karena lokasinya yang baru,django.urls

Django 2.0 ( tautan )

The django.core.urlresolversmodul dihapus mendukung lokasi baru, django.urls.

Jadi, cara yang benar untuk melakukannya adalah seperti ini:

from django.urls import resolve
current_url = resolve(request.path_info).url_name
Lukas Bünger
sumber
Mengapa? Sejauh saya memahami pertanyaan Anda, bagian penting darinya adalah bagaimana mencapai "Karena kita telah menamai url, kita perlu tahu bagaimana mendapatkan nama url yang disebut tampilan saat ini." ...
Lukas Bünger
1
Sebenarnya lukas aku kesal hari itu dan membuang jawabanmu dengan sembarangan. Saya minta maaf, karena ini jawaban yang benar. Saya akan mengeditnya agar lebih rumit.
e-satis
8
resolve()tidak dapat menyelesaikan jika Anda mengirimkannya string kueri dan hanya memunculkan 404. get_full_path()mengembalikan jalur dan string kueri. Anda perlu menggunakan resolve(request.path_info).
Can Burak Çilingir
Bagaimana jika bukan currenturl yang harus diselesaikan, tetapi, misalnya, yang akan dialihkan oleh pengguna? Apa cara yang lebih umum untuk melakukannya? Jawaban Conley Owens memiliki petunjuk, tetapi saya lebih suka tidak menemukan kembali roda jika roda tersebut sudah ada di Django di bawah kap mesin.
Hassan Baig
Tampaknya ini tidak berfungsi untuk url yang dapat diterjemahkan dengan i18n_patterns
guival
109

Pada Django 1.5, ini dapat diakses dari objek permintaan

    current_url = request.resolver_match.url_name

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

Bharathwaaj
sumber
Ketika saya memasukkan ini ke dalam prosesor konteks, itu berfungsi, tetapi kesalahan aneh ini ditunjukkan di konsol:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj
2
'Resolver_match' ditambahkan ke objek permintaan hanya setelah memanggil semua middleware permintaan. Saat itulah url diselesaikan. Jadi, Anda hanya dapat mengakses dari middleware tampilan dan seterusnya. (fungsi process_view dari middleware). Ini tidak akan tersedia dalam fungsi middleware permintaan. (fungsi process_request dari middleware).
Bharathwaaj
.view_namejika Anda memerlukan namespace
28

Bagi mereka yang menamai pola url mereka, maka Anda mungkin tertarik dengan nama url ber-namespace dari permintaan tersebut. Dalam kasus ini, Django memanggilnya sebagai view_namegantinya.

request.resolver_match.view_name

# return: <namespace>:<url name>
Yeo
sumber
Terima kasih, tapi ini cukup banyak penipuan dari jawaban sebelumnya @ dariusz-niespodziany, bukan? stackoverflow.com/a/31931833/1450294
Michael Scheper
5
Jika Anda tidak memberi namespace, urls.pymaka @ dariusz-niespodziany Anda akan langsung reverse-able. Tetapi jika Anda menggunakan namespace, maka resolver_match.url_nametidak dapat langsung- reversedapat. Jadi, Anda harus menambahkan namespace sendiri. Jadi, alih-alih melakukannya sendiri, Django sudah menyetel .view_namesaat inisialisasi.
Yeo
15

Ini dapat dicapai melalui:

    request.resolver_match.url_name

Django> 1.8

niespodd.dll
sumber
4

Klarifikasi dari pertanyaan: "Dalam pandangan, bagaimana Anda mendapatkan nama dari pola url yang mengarah ke sana, dengan asumsi persis ada satu pola url seperti itu."

Ini mungkin diinginkan karena alasan yang disebutkan: dari dalam tampilan, kami menginginkan cara KERING untuk mendapatkan url ke tampilan yang sama (kami tidak ingin harus mengetahui nama pola url kami sendiri).

Jawaban singkat: Ini tidak cukup sederhana untuk mengajar kelas Anda, tetapi mungkin akan menyenangkan bagi Anda untuk melakukannya dalam satu atau dua jam dan muntah di GitHub.

Jika Anda benar-benar ingin melakukan ini, Anda harus membuat subkelas RegexURLResolver dan memodifikasi metode penyelesaian untuk mengembalikan pola yang cocok (dari mana Anda bisa mendapatkan nama pola) alih-alih pasangan tampilan dan kata kunci / nilai. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

Anda kemudian dapat membuat dekorator atau mungkin lebih tepat middleware yang menggunakan subkelas ini untuk mendapatkan nama pola dan menyimpan nilai itu di suatu tempat dalam permintaan sehingga tampilan dapat menggunakannya.

Jika Anda benar-benar ingin melakukannya dan mengalami masalah, beri tahu saya dan saya mungkin bisa membantu.

Untuk kelas Anda, saya hanya akan meminta mereka melakukan hardcode nama pola dalam tampilan atau template. Saya yakin ini adalah cara yang dapat diterima untuk melakukannya.

Pembaruan: Semakin saya memikirkan hal ini, semakin saya tidak menyarankan untuk mencoba mendapatkan nama urlpattern dalam tampilan. Parameter urlpattern cukup independen dari parameter tampilan yang mereka tunjuk. Jika Anda ingin mengarahkan ke url tertentu, Anda perlu mengetahui cara kerja pola url, bukan hanya cara kerja tampilan. Jika Anda ingin mengetahui bagaimana pola url bekerja, Anda mungkin juga harus mengetahui nama dari pola url tersebut.

Conley Owens
sumber
3

Coba saja request.path. Itu akan membuat jalur saat ini diminta.

Abhishek Iyengar
sumber
1

Pertanyaan Anda sedikit tidak jelas, tetapi http://docs.djangoproject.com/en/dev/topics/http/urls/ kemungkinan akan memberikan penjelasan tentang apa yang Anda cari.

Sangat berguna untuk mencatat bagaimana Django memproses permintaan:

Ketika seorang pengguna meminta halaman dari situs Anda yang didukung Django, ini adalah algoritma yang diikuti sistem untuk menentukan kode Python mana yang akan dijalankan:

  1. Django menentukan modul root URLconf untuk digunakan. Biasanya, ini adalah nilai setelan ROOT_URLCONF, tetapi jika objek HttpRequest yang masuk memiliki atribut yang disebut urlconf (disetel oleh pemrosesan permintaan middleware), nilainya akan digunakan sebagai pengganti setelan ROOT_URLCONF.
  2. Django memuat modul Python itu dan mencari variabel urlpatterns. Ini harus berupa daftar Python, dalam format yang dikembalikan oleh fungsi django.conf.urls.defaults.patterns ().
  3. Django berjalan melalui setiap pola URL, secara berurutan, dan berhenti pada yang pertama yang cocok dengan URL yang diminta.
  4. Setelah salah satu regex cocok, Django mengimpor dan memanggil tampilan yang diberikan, yang merupakan fungsi Python sederhana. Tampilan diteruskan HttpRequest sebagai argumen pertamanya dan nilai apa pun yang ditangkap di regex sebagai argumen yang tersisa.

Jika Anda hanya mengejar jalur lengkap, Anda dapat mencoba:

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

Saya harap itu membantu - ini menunjukkan bagaimana menggunakan modul URLconf, dan mudah-mudahan akan membantu mengarahkan Anda ke arah yang benar.

Mark Mayo
sumber
Terima kasih, tetapi saya tahu bahwa :-) Saya menambahkan beberapa penjelasan untuk menghindari kesalahpahaman.
e-satis