Отримання URL-адреси адміністратора Django для об'єкта


168

Перед Django 1.0 був простий спосіб отримати URL-адресу адміністратора об'єкта, і я написав невеликий фільтр, який би я використовував так: <a href="{{ object|admin_url }}" .... > ... </a>

В основному я використовував функцію зворотного URL-адреси з назвою перегляду 'django.contrib.admin.views.main.change_stage'

reverse( 'django.contrib.admin.views.main.change_stage', args=[app_label, model_name, object_id] )

щоб отримати URL-адресу.

Як ви могли здогадатися, я намагаюся оновити до останньої версії Django, і це одна з перешкод, з якими я натрапив, що метод отримання URL-адреси адміністратора вже не працює.

Як я можу це зробити в django 1.0? (або 1.1 для цього, оскільки я намагаюся оновити до останньої версії в svn).

Відповіді:


61

У мене було подібне питання, де я намагався зателефонувати reverse('admin_index')і постійно отримував django.core.urlresolvers.NoReverseMatchпомилки.

Виявляється, у мене у файлі urls.py були старі URL-адреси адміністратора.

Це було в моїх URL-адресах:

(r'^admin/(.*)', admin.site.root),

який працює на екранах адміністратора, але це застарілий спосіб зробити це. Мені потрібно було змінити це на це:

(r'^admin/', include(admin.site.urls) ),

Як тільки я це зробив, все добро, що було обіцяно в документах URL-адрес зворотного адміністратора, почало працювати.


Чудово, це виправлено ще одну проблему, з якою у мене не було виклику методу get_urls () ModelAdmin. Дякую!
Арно

8
найкраща URL-адреса для цієї проблеми: docs.djangoproject.com/uk/dev/ref/contrib/admin/…
Дінго

4
Ця "відповідь" не є правильною, вона просто показує, як правильно додати додаток адміністратора до вашого додатку, що вирішило іншу проблему, яку мав автор. Справжня відповідь на власне питання - нижче - від markmuetz
Declan Shanaghy

Також потрібно мати зареєстрований адміністративний інтерфейс для моделі, інакше URL не буде існувати.
Flimm

412

Ви можете використовувати роздільник URL-адрес безпосередньо в шаблоні, не потрібно писати власний фільтр. Напр

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

{% url 'admin:polls_choice_change' choice.id %}

{% url 'admin:polls_choice_changelist' %}

Посилання: Документація


1
markmuetz - Чи є це в офіційних документах Django десь? (як використовувати зворотні URL-адреси адміністратора в шаблонах)? Якщо ні, так і має бути.
шейкер

7
shacker - Це все в документах ... просто не в одному місці. «URL» шаблонний тег документований тут . У розділі "Нове в Django 1.1:" документи говорять про те, що URL-адреси з просторим іменем добре, і вказують на розділ про простори імен URL-адрес . Приклеюючи все це, ви можете легко посилатися на додаток адміністратора у шаблонах. NB Я пам’ятаю, що документи писали різні, коли я писав відповідь.
markmuetz

3
Чи знаєте ви, як отримати посилання на "список" варіантів? Приклад: якщо "{% url admin: polls_choice_add%}" надає "/ admin / anlls / опитування / вибір / add", що було б еквівалентом, який би дав мені "/ admin / anlls / choice"?
DarwinSurvivor

2
{% URL адміністратора: polls_choice_changelist%} повертає '/ адміністратор / опитування / вибір' URL
LUC

35
Повернення URL-адреси адміністратора наразі повністю задокументовано тут https://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls
Джош Руссо

101
from django.core.urlresolvers import reverse
def url_to_edit_object(obj):
  url = reverse('admin:%s_%s_change' % (obj._meta.app_label,  obj._meta.model_name),  args=[obj.id] )
  return u'<a href="%s">Edit %s</a>' % (url,  obj.__unicode__())

Це схоже на рішення hansen_j, за винятком того, що він використовує простори імен URL-адреси , адміністратор: це простір імен додатків за замовчуванням для адміністратора.


3
Дякую, це допомагає. Я б змінив одне: використовувати args=[object.pk]замість args=[object.id]. Він охоплює більш поширений випадок, коли поле первинного ключа має інше ім'я, ніж id.
стебло

5
Хороша відповідь. FYI будь-кому, хто використовує нещодавнє django, потрібно буде змінити object._meta.module_name на object._meta.model_name
Jagu

Велике спасибі від новачка джанго. object._meta.app_labelдозвольте мені в кінцевому підсумку отримати назву власного додатку для аутентифікації джанго. Це auth, наприклад , reverse(admin:auth_user_change, args=[object.id])щоб перейти на сторінку користувача зміни
Грет

2
Обов’язково змініть об'єкт на obj. Цей хлопець над написанням зарезервованого вбудованого символу.
Кевін Паркер

17

Існує ще один спосіб для пізніших версій, наприклад в 1.10 :

{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>

Де optsщось подібне mymodelinstance._metaчиMyModelClass._meta

Один момент - це те, що ви не можете отримати доступ до атрибутів підкреслення безпосередньо в шаблонах Django (як {{ myinstance._meta }}), тому вам доведеться передати optsоб'єкт з подання як контексту шаблону.


2
URL документа змінився! Дивіться: docs.djangoproject.com/en/1.9/ref/contrib/admin/…
Wim Feijen

12

По суті такий же, як відповідь Майка Раміреса, але простіший і стилістичніший до стандартного get_absolute_urlметоду джанго :

def get_admin_url(self):
    return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name),
                   args=[self.id])

11

Для django до 1.1 це просто (для екземпляра сайту адміністратора за замовчуванням):

reverse('admin_%s_%s_change' % (app_label, model_name), args=(object_id,))

8
З новим простором імен це адміністратор:% s_% s_change
Teebes

3

Якщо ви використовуєте 1.0, спробуйте зробити спеціальний тег шаблонів, який виглядає приблизно так:

def adminpageurl(object, link=None):
    if link is None:
        link = object
    return "<a href=\"/admin/%s/%s/%d\">%s</a>" % (
        instance._meta.app_label,
        instance._meta.module_name,
        instance.id,
        link,
    )

тоді просто використовуйте {% adminpageurl my_object%} у своєму шаблоні (не забудьте спочатку завантажити тег шаблонів)


1

Я вирішив це, змінивши вираз на:

reverse( 'django-admin', args=["%s/%s/%s/" % (app_label, model_name, object_id)] )

Це вимагає / припускає, що коренева URL-адреса має назву обробника URL-адреси "admin", головним чином це ім'я "django-admin",

тобто в кореневій URL-адресі конф:

url(r'^admin/(.*)', admin.site.root, name='django-admin'),

Здається, це працює, але я не впевнений у його чистоті.


2
Це працює для 1,0, але не спрацює для 1,1, що є кращим рішенням: див. Відповідь Олексія Кошелєва.
Карл Мейєр

Насправді я спробував це, і це не вийшло, і він сказав, що це за 1,0, ні?
hasen

Синтаксис змінився в 1.1 із введенням простору імен URL-адрес: docs.djangoproject.com/en/dev/topics/http/urls/…
sleepyjames

-1

Ось ще один варіант використання моделей:

Створіть базову модель (або просто додайте метод admin_link до певної моделі)

class CommonModel(models.Model):
    def admin_link(self):
        if self.pk:
            return mark_safe(u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' % (self._meta.app_label,
                    self._meta.object_name.lower(), self.pk, self))
        else:
            return mark_safe(u'')
    class Meta:
        abstract = True

Спадщина від цієї базової моделі

   class User(CommonModel):
        username = models.CharField(max_length=765)
        password = models.CharField(max_length=192)

Використовуйте його в шаблоні

{{ user.admin_link }}

Або переглянути

user.admin_link()

2
Я не думаю, що це хороше рішення. Створення URL-адреси з форматуванням рядків - шкідлива звичка. Будь ласка, використовуйте зворотний ().
guettli
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.