web-dev-qa-db-de.com

Django Klassenbasierte Ansicht: Wie übergebe ich zusätzliche Parameter an die as_view-Methode?

Ich habe eine benutzerdefinierte klassenbasierte Ansicht

# 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)

Ich möchte den Slug-Parameter (oder andere Parameter an die Ansicht) wie folgt übergeben

MyView.as_view(slug='hello_world')

Muss ich Methoden überschreiben, um dies zu tun?

87
Rudolf Olah

Jeder Parameter, der an die Methode as_view Übergeben wird, ist eine Instanzvariable der View-Klasse. Das heißt, um slug als Parameter hinzuzufügen, müssen Sie es als Instanzvariable in Ihrer Unterklasse erstellen:

# 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)

Damit sollte MyView.as_view(slug='hello_world') funktionieren.

Wenn Sie die Variablen über Schlüsselwörter weitergeben, verwenden Sie die Vorschläge von Herrn Erikkson: https://stackoverflow.com/a/11494666/99

82
Rudolf Olah

Wenn deine URL so aussieht:

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

dann wird der Slug in Ihren Ansichtsfunktionen (wie 'get_queryset') wie folgt verfügbar sein:

self.kwargs['slug']
107
Daniel Eriksson

Beachten Sie, dass Sie get_object() nicht überschreiben müssen, um ein Objekt zu suchen, das auf einem als Schlüsselwort arg übergebenen Slug basiert. Sie können die Attribute eines SingleObjectMixinhttps: //docs.djangoproject.com/de/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 }}

(beide slug_field und slug_url_kwarg standardmäßig 'slug')

18
Fush

Wenn Sie dem Kontext für die Vorlage ein Objekt hinzufügen möchten, können Sie get_context_data Überschreiben und dem Kontext hinzufügen. Die Anfrage ist auch Teil von self, falls Sie request.user benötigen.

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
13
Aleck Landgraf

Sie können Parameter von urls.py https://docs.djangoproject.com/de/1.7/topics/http/urls/#passing-extra-options-to-view-functions übergeben

Dies funktioniert auch für allgemeine Ansichten. Beispiel:

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

In diesem Fall müssen die an die Ansicht übergebenen Parameter nicht unbedingt Instanzvariablen der Ansichtsklasse sein. Mit dieser Methode müssen Sie den Standardseitennamen nicht fest in Ihr YourView-Modell einprogrammieren, sondern können ihn einfach als Parameter von urlconf übergeben.

10

Wie von Yaroslav Nikitenko angegeben, können Sie zusätzliche Optionen an Anzeigefunktionen übergeben von urls.py so was:

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

Ich wollte nur hinzufügen, wie man es aus der Ansicht verwendet. Sie können eine der folgenden Methoden implementieren:

# 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
7
Emile Bergeron