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
*argsy 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: enurls.py, cuando escribes algo comoMyView.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 comoinitkwargs. - 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 losinitkwargsal constructor, almacena larequest,*argsy**kwargsen los mismos atributos en la instancia CBV, y finalmente llama adispatch()en la instancia. - Y aquí viene uno de esos detalles confusos: los mismos argumentos
request,*argsy**kwargstambién serán pasados adispatch()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 aget(),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
initkwargsse almacenan de forma redundante envvv.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 usarvanilla-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)
initkwargsque se derivan de los argumentos de palabra clave individuales para el método de fábrica de vistaas_view()y terminarán como atributos individuales de la instancia de clase CBV y (2)kwargsque provienen de grupos con nombre en su instancia de urlconf y termina como (2a) argumentos de palabra clave para las llamadas a sus métodosget()ypost()así como, confusamente, (2b) un atributokwargsen su instancia de clase CBV. - Entonces, ¿ cuál debería usar , el argumento
kwargso 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
kwargsloskwargsa menudo sí tienen un parámetrokwargssí mismos ...
Moral: Prefiera self.kwargs sobre el argumento kwargs siempre que sea posible y no permita que initkwargs confunda.