Получение админки 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).

Hasen
источник

Ответы:

61

У меня была похожая проблема, когда я пытался позвонить, reverse('admin_index')и постоянно получал django.core.urlresolvers.NoReverseMatchошибки.

Оказывается, в моем файле urls.py были адреса администратора старого формата.

У меня было это в моих urlpatterns:

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

который заставляет работать административные экраны, но является устаревшим способом сделать это. Мне нужно было изменить это на это:

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

Как только я это сделал, все добро, которое было обещано в документах с реверсивными админскими URL-адресами, начало работать.

bskinnersf
источник
Круто, это исправило еще одну проблему, которая у меня возникла, когда не вызывался метод get_urls () ModelAdmin. Спасибо!
Арно
8
лучший URL для этой проблемы: docs.djangoproject.com/en/dev/ref/contrib/admin/…
Динго
4
Этот «ответ» не верен, он просто показывает, как правильно добавить приложение администратора в ваше приложение, что решило другую проблему, с которой столкнулся автор. Реальный ответ на актуальный вопрос ниже - от Markmuetz
Declan Shanaghy
Кроме того, вам нужно иметь зарегистрированный интерфейс администратора для модели, иначе URL не будет существовать.
Флим
412

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

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Ссылка: Документация

markmuetz
источник
1
markmuetz - это где-нибудь в официальных документах Django? (как использовать обратные URL-адреса администратора в шаблонах)? Если нет, то должно быть.
шейкер
7
шейкер - это все в документах ... только не в одном месте. Тег шаблона "url" задокументирован здесь . В разделе «Новое в Django 1.1:» документы говорят, что URL-адреса с пространством имен подходят, и указывают на раздел о пространствах имен URL-адресов . Объединение всего этого позволяет легко ссылаться на приложение администратора в шаблонах. NB. Я помню, что документы были другими, когда я писал ответ.
markmuetz
3
Знаете ли вы, как получить ссылку на «список» вариантов? Пример: если "{% url admin: polls_choice_add%}" дает "/ admin / polls / choice / add", что будет эквивалентным мне "/ admin / polls / choice"?
DarwinSurvivor
2
{% url admin: polls_choice_changelist%} возвращает url '/ admin / polls / choice'
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 , admin: это пространство имен приложения администратора по умолчанию.

Майк Рамирес
источник
3
Спасибо, это помогает. Одна вещь, которую я хотел бы изменить: использовать args=[object.pk]вместо args=[object.id]. Он охватывает более распространенный случай, когда поле первичного ключа имеет другое имя, чем id.
стебель
5
Хороший ответ. FYI кто использует более свежую Джанго необходимо изменить object._meta.module_name к object._meta.model_name
Jagu
Большое спасибо от новичка Джанго. object._meta.app_labelпозвольте мне в конечном итоге получить имя для собственного приложения аутентификации Django. Это auth, например , reverse(admin:auth_user_change, args=[object.id])чтобы перейти на страницу пользователя изменения
Грет
2
Обязательно измените объект на объект. Этот парень закончил писать зарезервированный встроенный символ.
Кевин Паркер
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объект из представления как контекст шаблона.

Anentropic
источник
2
URL-адрес документа изменился! См .: docs.djangoproject.com/en/1.9/ref/contrib/admin/…
Вим Фейен,
12

По сути то же самое, что и ответ Майка Рамиреса, но проще и ближе по стилистике к стандартному get_absolute_urlметоду django :

def get_admin_url(self):
    return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name),
                   args=[self.id])
Энтони Хэтчкинс
источник
11

Для pre 1.1 django это просто (для экземпляра сайта администратора по умолчанию):

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%} в своем шаблоне (не забудьте сначала загрузить тег шаблона)

DarwinSurvivor
источник
1

Я решил это, изменив выражение на:

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

Это требует / предполагает, что у корневого URL-адреса есть имя для обработчика URL-адреса «admin», в основном это имя «django-admin»,

т.е. в корне url conf:

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

Вроде бы работает, но я не уверен в его чистоте.

Hasen
источник
2
Это работает для 1.0, но не будет работать для 1.1, который имеет лучшее решение: см. Ответ Алексея Кошелева.
Карл Мейер
На самом деле я попробовал это, и это не сработало, и он сказал, что это для 1.0, нет?
Хазен
Синтаксис изменился в 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 с форматированием строки - плохая привычка. Пожалуйста, используйте реверс ().
Геттли