Class Views in Django

Django points to a function, which can be a problem if you want to change just a little functionality. Yes, I could have a million keyword arguments, and even more if the instructions are in a function, but I was thinking more about an object-oriented approach.

For example, I have a page displaying a user. This page is very similar to the page displaying the group, but it is still not very similar to another data model. The group also has members, etc.

One way is to point to the methods of the class, and then extend this class. Has anyone tried this approach or have any other idea?

+41
python oop django views
Aug 3 '08 at 15:55
source share
9 answers

I created and used my own generic presentation classes, defining __call__ so that the class instance is called. I really like it; while Django general views allow some customization using keyword arguments, OO general views (if their behavior is divided into several separate methods) can have much finer tuning through a subclass, which allows me to repeat myself a lot less. (I'm tired of rewriting the same presentation / update logic anytime when I need to configure something that Django does not completely allow).

I posted the djangosnippets.org code.

The only real drawback that I see is the spread of internal method calls, which can slightly affect performance. I do not think this is of great concern; it is rare that Python code execution will be your performance bottleneck in a web application.

UPDATE : Django's own generic views are now class based.

UPDATE : FWIW, I changed my mind about classes since this answer was written. After they have been widely used in several projects, I feel that they tend to lead to code that is satisfactory DRY to write, but very difficult to read and maintain later, because the functionality spreads in many different places, and subclasses are so dependent on every detail of the implementation of superclasses and mixins. Now I feel that TemplateResponse and viewing decorators is the best answer for decomposing view code.

+39
Aug 29 '08 at 4:29
source share

I needed to use class-based views, but I wanted to be able to use the fully qualified class name in my URLconf, without having to create an instance of the view class before using it. What helped me was an amazingly simple metaclass:

 class CallableViewClass(type): def __call__(cls, *args, **kwargs): if args and isinstance(args[0], HttpRequest): instance = super(CallableViewClass, cls).__call__() return instance.__call__(*args, **kwargs) else: instance = super(CallableViewClass, cls).__call__(*args, **kwargs) return instance class View(object): __metaclass__ = CallableViewClass def __call__(self, request, *args, **kwargs): if hasattr(self, request.method): handler = getattr(self, request.method) if hasattr(handler, '__call__'): return handler(request, *args, **kwargs) return HttpResponseBadRequest('Method Not Allowed', status=405) 

Now I can both create instances of class classes and use instances as view functions. OR I can just point my URLconf to my class and create a metaclass (and call) a view class for me. This works by checking the first argument for __call__ - if it is a HttpRequest , it should be the actual HTTP request, because it would be pointless to try to create an instance of the class with an HttpRequest instance.

 class MyView(View): def __init__(self, arg=None): self.arg = arg def GET(request): return HttpResponse(self.arg or 'no args provided') @login_required class MyOtherView(View): def POST(request): pass # And all the following work as expected. urlpatterns = patterns('' url(r'^myview1$', 'myapp.views.MyView', name='myview1'), url(r'^myview2$', myapp.views.MyView, name='myview2'), url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'), url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'), ) 

(I posted a snippet for this at http://djangosnippets.org/snippets/2041/ )

+13
May 27 '10 at 13:02
source share

If you're just showing data from models, why not use Django Generic Views ? They are designed so that you can easily derive data from the model without having to write your own view and information on mapping URL parameters to view, receive data, handle extreme cases, render rendering, etc.

+9
Aug 07 '08 at 10:44
source share

You can always create a class, override the __call__ function, and then specify the URL file to the class instance. You can look at the FormWizard class to see how this is done.

+3
Aug 26 '08 at 11:38
source share

It sounds to me as if you are trying to combine things that should not be combined. If you need to perform other processing in your view, depending on which user or group object you are trying to view, then you should use two different viewing functions.

On the other hand, there may be general idioms that you want to extract from your representations of type object_detail ... maybe you could use a decorator or just helper functions?

Dan

+2
Aug 03 '08 at 17:40
source share

If you want to do something a little complicated, using general views is the way to go. They are much more powerful than their name, and if you just show the model data, the general ideas will do the job.

+2
Aug 11 '08 at 22:59
source share

If you want to share common functionality between pages, I suggest you look at custom tags. They are quite easy to create and very powerful.

In addition, templates may apply to other templates . This allows you to create a basic template for customizing the page layout and share it between other templates that fill in the blanks. You can nest patterns at any depth; allowing you to specify the layout in separate groups of related pages in one place.

+1
Aug 26 '08 at 11:30
source share

General views should generally go, but in the end you can handle the URLs as you want. FormWizard does things based on classes, as well as some RESTful API applications.

Basically, with a URL, you are provided with a bunch of variables and a place to provide the called, what you call is completely up to you - the standard way is to provide a function, but ultimately Django does not impose any restrictions on what you do.

I agree that a few more examples of how to do this would be nice, FormWizard is probably the place to start.

+1
Sep 23 '08 at 19:05
source share

You can use general Django views. You can easily achieve the desired functionality. Full Django Views.

+1
Oct 08 '14 at 5:53 on
source share



All Articles