[Django]-CRUD pattern for urls.py, passing object from URI to view

4đź‘Ť

âś…

Yes, you can do this, and I’ve done it. The Django generic views don’t support it directly. You need to wrap the generic view with your own view that looks up the model and constructs the queryset. Here’s an example (showing only the detail view, you can do the others similarly). I’ve changed your named patterns in the URLconf to use “model” instead of “object”, which is clearer naming:

in urls.py:

url(r'^(?P<model>\w+)/(?P<object_id>\d+)/$', 'my_app.views.my_object_detail',  name='object_detail'),

in my_app/views.py

from django.views.generic.list_detail import object_detail
from django.db.models.loading import get_model
from django.http import Http404

def get_model_or_404(app, model):
    model = get_model(app, model)
    if model is None:
        raise Http404
    return model

def my_object_detail(request, model, object_id):
    model_class = get_model_or_404('my_app', model)
    queryset = model_class.objects.all()
    return object_detail(request, queryset, object_id=object_id)

If you’re clever and want to keep things as DRY as possible, you could create a single wrapper that accepts the generic view function to call as one of its arguments, rather than having a wrapper for create, a wrapper for update, etc.

👤Carl Meyer

1đź‘Ť

I think you might be a bit confused about what the generic views are designed to do. If you go and read django.views.generic.list_detail, for instance, you will see that neither object_list nor object_detail accept an “object” argument, but both require a “queryset” argument. You don’t need to “find the corresponding Model” – both generic views are simply common ways to render the provided queryset (in the case of object_detail, after being filtered by either object_id or slug and slug_field). I’m not entirely sure what you’re trying to do but I don’t think these generic views are what you’re looking for.

👤ozan

Leave a comment