This commit is contained in:
Víðir Valberg Guðmundsson 2023-06-21 13:57:10 +02:00
parent 1457a3a408
commit 6e4407218e

View file

@ -53,7 +53,7 @@ Can we apply the same pattern to Django? Yes we can!
# Introducing django-view-decorator! # Introducing django-view-decorator!
`django-view-decorator` is my attempt to implement a decorator which can be used to apply this pattern to Django views. [`django-view-decorator`](https://github.com/valberg/django-view-decorator/) is my attempt to implement a decorator which can be used to apply this pattern to Django views.
The project is very much under development, and it is currently in the "research and development" phase. But it does work! The project is very much under development, and it is currently in the "research and development" phase. But it does work!
@ -148,13 +148,29 @@ Here is a step-by-step for what is going on:
2. The `ready` method calls `autodiscover_modules` from `django.utils.module_loading`. This imports `views.py` files from all apps in `INSTALLED_APPS`. The admin does the same thing, it just imports `admin.py` files. 2. The `ready` method calls `autodiscover_modules` from `django.utils.module_loading`. This imports `views.py` files from all apps in `INSTALLED_APPS`. The admin does the same thing, it just imports `admin.py` files.
3. By importing a `views.py` file we run all `@view()` invocations 3. By importing a `views.py` file we run all `@view()` invocations
4. In `view` decorator we gather information provided as arguments to the decorator and store this in a registry which is located at `django_view_decorator.apps.ViewRegistry`. 4. In `view` decorator we gather information provided as arguments to the decorator and store this in a registry which is located at `django_view_decorator.apps.ViewRegistry`.
5. We can now use `ViewRegistry.urlpatterns()` to get the `urlpatterns` for all registrered views. 5. We can now use `ViewRegistry.urlpatterns()` to get the `urlpatterns` for all registrered views. The `include_view_urls` helper function exists to do exactly this.
There are of course some small "buts and ifs" sprinkled around, but by and large this is how the whole thing works. There are of course some small "buts and ifs" sprinkled around, but by and large this is how the whole thing works.
One thing to note is that since we are only looking for `views.py` modules, views placed in other modules will not be picked up. To solve this the `include_view_urls` function takes a `extra_modules` arguments which works like so:
:::python
# project/urls.py
from django.urls import path
from django_view_decorator import include_view_urls
urlpatterns = [
path("", include_view_urls(
extra_modules=["foos.special_views"]
))
]
This would include views from `foos/special_views.py` in the registry.
## Namespaces and the power of factories ## Namespaces and the power of factories
In our more advanced example you might have noticed the `namespace="foos"`, which probably is going to quite tedious to repeat over and over again. One of the nice things about Django URLconfs is that we get namespacing by using the `include` function. In our more advanced example you might have noticed the `namespace="foos"`, which probably is going to quite tedious to repeat over and over again. In vanilla Django URLconfs we get namespacing by using the `include` function. So how do we do namespacing with this new pattern?
This is where the aptly named `namespaced_decorator_factory` comes into the picture. Let us look at an example: This is where the aptly named `namespaced_decorator_factory` comes into the picture. Let us look at an example:
@ -232,7 +248,7 @@ Newcomers would learn that to hook up views to URLs they register their views in
## The path to Django core ## The path to Django core
So, as I wrote initially, I have a mission to try to get this pattern into Django core. This is not going to be an easy feat. So, as I wrote initially, I have a mission to try to get this pattern into Django core. This is not going to be an easy feat, but I want to be upfront about my plan. Partly because I think it is going to enhance my chances of succeeding, but also so the current project can move in the right direction.
To cite Carlton Gibson from the previously mentioned talk: To cite Carlton Gibson from the previously mentioned talk:
@ -245,6 +261,10 @@ So this is what I'm doing.
3. Gather community interest - ongoing 3. Gather community interest - ongoing
4. Merge! 4. Merge!
My best case scenario would be to land it in Django 5.1, but then I'm close to daydreaming.
No matter whether my plan to get this pattern, in some form or another, into Django will succeed, I will continue to maintain `django-view-decorator` as an alternative to the current `views.py/urls.py` approach.
## What do you think? ## What do you think?
So now I'm throwing the ball to the Django community! So now I'm throwing the ball to the Django community!