Django 2.1 - Отображение verbose_name модели из мета в ListView - PullRequest
0 голосов
/ 19 марта 2019

Первый раздел кода работает нормально;это для справки.

#Basic Model
class MyTestModel(models.Model):
    record = models.CharField(max_length=100)

    def __str__(self):
        return self.record

    #Specify verbose_name
    class Meta:
        verbose_name = 'UniqueNameExample'
        verbose_name_plural = verbose_name


#Generic ListView.
class MyTemplateView(ListView):
    model = MyTestModel
    template_name = 'base.html'
    context_object_name = 'model_list'
    ordering = ['record']



#Python block in HTML template. So far, so good. 
{% for item in model_list %}
    {{ item.record }}<br>
    #{{ item }} also works
{% endfor %}

Я пытаюсь получить доступ к verbose_name модели ('UniqueNameExample') И model_list в представлении.Я попытался зарегистрировать фильтр, тег и simple_tag.

Что-то вроде: templatetags / verbose.py

from django import template
register = template.Library()

@register.filter (or @register.tag or @register.simple_tag)
def verbose_name(obj):
    #Could be verbose_name(model) or whatever input
    return obj._meta.verbose_name

А потом после

{% load verbose %}

в моем HTML (что тоже хорошо работает) я попробую что-токак это:

{{ object|verbose_name }}

И я получу сообщение об ошибке 'str' объект не имеет атрибута _meta.Ошибка та же, если использовать тег:

{% verbose_name object %}

Примечание: теги, видимо, работали для более ранних версий, но, возможно, я их неправильно использую?Не запрашивая доступ к полю Модель verbose_name для «записи», кстати - это ответили адекватно на SO.

Одна вещь, которую я попробовал, наполовину правильный ответ, - это если я установлю следующее в MyTemplateView:

queryset = model._meta.verbose_name 

Проблема в том, что он переопределяет model_list, и единственноеВ результате у меня осталось «UniqueNameExample» без возможности доступа к записям, которые я использовал в модели.

Я знаю private = True для _meta (не уверен, что это уместно или стоит исследовать / возможно сломать), но администратор Django отображает verbose_name (если установлено) в списке созданных моделей, поэтому я не вижупочему я не могу сделать то же самое (также пришлось грубо проследить, как именно это происходит в исходном коде).Может быть, это не универсальный ListView, а MixIn?На основе функций?

Большая (ish) дБ с тысячами моделей, каждая с уникальным verbose_name [s];очень бы хотелось, чтобы все было просто.

1 Ответ

0 голосов
/ 20 марта 2019

РЕДАКТИРОВАТЬ: нашел фантастическое решение от Доминик Бартон @ https://blog.confirm.ch/accessing-models-verbose-names-django-templates/

Сначала создайте папку templatags на уровне приложения и заполните файл инициализации. Затем создайте файл шаблона тега. Что-то вроде verbose.py.

from django import template
register = template.Library()

@register.simple_tag
def verbose_name(value):
#Django template filter which returns the verbose name of a model.
#Note: I set my verbose_name the same as the plural, so I only need one tag. 
    if hasattr(value, 'model'):
        value = value.model
    return value._meta.verbose_name

Затем ListView должен быть изменен.

from django.views.generic.list import ListView as DjangoListView
from .models import MyTestModel


class ListView(DjangoListView):
    #Enhanced ListView which includes the `model` in the context data,
    #so that the template has access to its model class.
    #Set normally
    model = MyTestModel
    template_name = 'base.html'
    context_object_name = 'model_list'
    ordering = ['record']

    def get_context_data(self):
        #Adds the model to the context data.
        context = super(ListView, self).get_context_data()
        context['model'] = self.model
        return context

Не забудьте добавить путь к urls.py:

path('your_extension/', views.ListView.as_view(), name='base')

Наконец, загрузите тег и итерируйте «записи» в обычном режиме:

{% load verbose %}


<h1> {% verbose_name model%} </h1>

<ul style='list-style:none'>
{% for item in model_list %}
    <li>{{ item }}}</a></li> 
{% endfor %}
</ul>

Нумерация страниц также работает как рекламируется.

...