vistas tutorial queryset genericas django django-views django-class-based-views

queryset - django tutorial



Manejo de los argumentos clave kwargs en las vistas basadas en clases de Django(CBV) (1)

Me acerqué peligrosamente a la locura cuando (al ser un principiante de Django) no pude acceder a un objeto modelo por medio de la clave primaria pk (proveniente de la URL) en mi subclase FormView e intenté entender cómo hacerlo bien . Es confuso.

Entonces, ¿cómo se pasan los argumentos de las palabras clave en los CBV genéricos y cómo se deben manejar y usar?

(Y voy a contestarme a mí mismo, porque lo descubrí y lo escribí para entenderlo correctamente).


No confundas kwargs con esos otros kwargs ...

  • Recuerde que una vista eventualmente siempre es una función. Como puede recordar de "Cómo procesa Django una solicitud" , los grupos sin nombre de la expresión regular urlconf se pasarán a la vista como *args y los grupos nombrados como **kwargs .
  • Pero para un CBV es menos obvio cuál es esa función de vista en realidad o qué hace, porque está oculta profundamente en Django. Como recordará de "Uso de vistas basadas en clases" , la función as_view() un CBV creará y devolverá la función de vista real.
  • Así que aquí es lo primero que hay que recordar sobre el manejo de kwargs : en urls.py , cuando escribes algo como MyView.as_view(myarg=myvalue) , cada argumento de palabra clave anulará el atributo de clase con el mismo nombre de la clase CBV en el CBV ejemplo. Esos argumentos se conocen como initkwargs .
  • La función de vista que realmente se ejecutará (vamos a llamarlo vvv ) es una genérica definida en django.views.generic.base . Crea una instancia de su CBV, pasa los initkwargs al constructor, almacena la request , *args y **kwargs en los mismos atributos en la instancia CBV, y finalmente llama a dispatch() en la instancia.
  • Y aquí viene uno de esos detalles confusos: los mismos argumentos request , *args y **kwargs también serán pasados ​​a dispatch() directamente. (Escribo llamada parens para indicar métodos en oposición a los atributos de datos; los parientes vacíos no significan que no hay argumentos).
  • dispatch() examina la solicitud y llama a get() , post() , head() etc., según el tipo de solicitud, pasando de nuevo los argumentos.
  • Y hay más redundancia a la vuelta de la esquina: los initkwargs se almacenan de forma redundante en vvv.view_initkwargs . (Trate de olvidar esto rápidamente, rara vez lo necesitará).
  • Una vez que se llama a la vista así creada, los kwargs "reales" se pasan a varios métodos de manejo de solicitudes en las diversas subclases de vista genéricas y se ven las clases mixin. La estructura de esas clases, sin embargo, puede volverte loco. Si está interesado en preservar su salud mental, le recomiendo usar vanilla-views
    como reemplazo de los CBV genéricos incorporados de Django. El paquete proporciona las mismas capacidades en una forma mucho más simple.
  • Entonces, para resumir: hay (1) initkwargs que se derivan de los argumentos de palabra clave individuales para el método de fábrica de vista as_view() y terminarán como atributos individuales de la instancia de clase CBV y (2) kwargs que provienen de grupos con nombre en su instancia de urlconf y termina como (2a) argumentos de palabra clave para las llamadas a sus métodos get() y post() así como, confusamente, (2b) un atributo kwargs en su instancia de clase CBV.
  • Entonces, ¿ cuál debería usar , el argumento kwargs o el atributo? Esta publicación argumenta que el uso del atributo es más natural para un CBV y que también hará que el código sea más uniforme, porque el argumento no está disponible en todos los lugares dentro del marco CBV.
  • Y esta es la fuente final de la confusión: los métodos para los que no se kwargs los kwargs a menudo tienen un parámetro kwargs sí mismos ...

Moral: Prefiera self.kwargs sobre el argumento kwargs siempre que sea posible y no permita que initkwargs confunda.