Представление на основе класса Django: как передать дополнительные параметры методу as view?

у меня есть пользовательский класс в виде

# myapp/views.py
from django.views.generic import *

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

Я хочу передать параметр slug (или другие параметры в представление), как это

MyView.as_view(slug='hello_world')

нужно ли переопределять какие-либо методы, чтобы сделать это?

6 ответов


Если ваш urlconf выглядит примерно так:

url(r'^(?P<slug>[a-zA-Z0-9-]+)/$', MyView.as_view(), name = 'my_named_view')

тогда пуля будет доступна внутри ваших функций просмотра (например, "get_queryset"), например:

self.kwargs['slug']

каждый параметр, который передается as_view method является переменной экземпляра класса View. Это означает добавить slug в качестве параметра вы должны создать его как переменную экземпляра в своем подклассе:

# myapp/views.py
from django.views.generic import DetailView

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel
    # additional parameters
    slug = None

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

что нужно делать MyView.as_view(slug='hello_world') работа.

если вы передаете переменные через ключевые слова, используйте то, что предложил г-н Эриксон:https://stackoverflow.com/a/11494666/9903


стоит отметить, что вам не нужно переопределять get_object() чтобы найти объект на основе слизняка, переданного как ключевое слово arg - вы можете использовать атрибуты SingleObjectMixin https://docs.djangoproject.com/en/1.5/ref/class-based-views/mixins-single-object/#singleobjectmixin

# views.py
class MyView(DetailView):
    model = MyModel
    slug_field = 'slug_field_name'
    slug_url_kwarg = 'model_slug'
    context_object_name = 'my_model'

# urls.py
url(r'^(?P<model_slug>[\w-]+)/$', MyView.as_view(), name = 'my_named_view')

# mymodel_detail.html
{{ my_model.slug_field_name }}

(как slug_field и slug_url_kwarg по умолчанию 'slug')


Если вы хотите добавить объект в контекст шаблона, который вы можете переопределить get_context_data и добавьте в его контекст. Запрос также является частью self в случае, если вам нужна запрос..

def get_context_data(self, **kwargs):
        context = super(MyTemplateView, self).get_context_data(**kwargs)
        if 'slug' in self.kwargs:
            context['object'] = get_object_or_404(MyObject, slug=self.kwargs['slug'])
            context['objects'] = get_objects_by_user(self.request.user)

        return context

вы можете передать параметры от urls.py https://docs.djangoproject.com/en/1.7/topics/http/urls/#passing-extra-options-to-view-functions

Это также работает для общего представления. Пример:

url(r'^$', views.SectionView.as_view(), { 'pk': 'homepage', 'another_param':'?'}, name='main_page'),

в этом случае параметры, передаваемые в представление не обязательно должно переменные экземпляра класса View. Используя этот метод, вам не нужно жестко кодировать имя страницы по умолчанию в модель YourView, но вы можете просто передать его как параметр из url-конфигурации.


как заявил Ярослав Никитенко, если вы не хотите жестко закодировать новую переменную экземпляра в класс View, вы можете передать дополнительные опции для просмотра функций С urls.py такой:

url(r'^$', YourView.as_view(), {'slug': 'hello_world'}, name='page_name')

Я просто хотела добавить, как использовать его из виду. Вы можете реализовать один из следующих методов:

# If slug is optional
def the_function(self, request, slug=None):
    # use slug here

# if slug is an optional param among others
def the_function(self, request, **kwargs):
    slug = kwargs.get("slug", None)
    other_param = kwargs.get("other_param", None)

# If slug is required
def the_function(self, request, slug):
    # use slug here