Pregunta Vista basada en clases de Django: ¿cómo paso parámetros adicionales al método as_view?


Tengo una vista personalizada basada en clase

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

Quiero pasar el parámetro slug (u otros parámetros a la vista) como este

MyView.as_view(slug='hello_world')

¿Debo anular cualquier método para poder hacer esto?


73
2017-07-15 18:26


origen


Respuestas:


Si tu urlconf se ve así:

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

entonces el slug estará disponible dentro de las funciones de visualización (como 'get_queryset') de esta manera:

self.kwargs['slug']

94
2017-07-15 18:54



Cada parámetro que se pasa al as_view método es una variable de instancia de la clase View. Eso significa agregar slug como parámetro, debe crearlo como una variable de instancia en su subclase:

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

Eso debería hacer MyView.as_view(slug='hello_world') trabajo.

Si pasa las variables a través de palabras clave, use lo que sugirió el Sr. Erikkson: https://stackoverflow.com/a/11494666/9903


64
2017-07-15 19:04



Vale la pena señalar que no es necesario anular get_object() para buscar un objeto basado en un slug pasado como una palabra clave arg, puede usar los atributos de 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 }}

(ambos slug_field y slug_url_kwarg predeterminado a 'slug')


16
2018-06-19 03:17



Si desea agregar un objeto al contexto de la plantilla, puede anular get_context_data y agregar a su contexto. La solicitud también es parte de yo en caso de que necesites el request.user.

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
2017-10-08 18:24



Puede pasar parámetros desde urls.py https://docs.djangoproject.com/en/1.7/topics/http/urls/#passing-extra-options-to-view-functions

Esto también funciona para vistas genéricas. Ejemplo:

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

En este caso, los parámetros pasados ​​a la vista no deben ser necesariamente variables de instancia de la clase View. Con este método no es necesario codificar el nombre de página predeterminado en el modelo YourView, pero puedes pasarlo como parámetro desde urlconf.


8
2018-03-26 21:12



Según lo declarado por Yaroslav Nikitenko, si no quiere codificar una nueva variable de instancia en la clase View, puede pasar opciones adicionales para ver funciones de urls.py Me gusta esto:

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

Solo quería agregar cómo usarlo desde la vista. Puede implementar uno de los siguientes métodos:

# 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
2018-05-12 19:53