AJAX, django signals, and class based view awesomeness.
I’ve started using a combination of class based views and signals that is very powerful and extensible.
A personalized class based view base class
I’ve set up a BaseView class in my project which inherits from django.views.generic.base.View that sets sensible defaults for my AJAX classes.
For example, I have an AJAXBaseView class which defines four attributes: errors, messages, data, and success. It also has a response_data property that formats the data in a specific way for my JavaScript.
This setup ensures I use the same format for my ajax responses across my project.
class AJAXBaseView(View):
def __init__(self, *args, **kwargs):
super(BaseView, self).__init__(*args, **kwargs)
# set sensible default class instance attributes.
self.errors = []
self.messages = []
self.data = {}
self.success = False
@property
def response_data(self):
"""
Format response data
"""
return {
'success': self.success,
'errors': self.errors,
'data': self.data,
'messages': self.messages,
}
class MyAJAXView(AJAXBaseView):
def get(self, request):
some_signal.send(sender=MyAJAXView, instance=self)
# modifies instance.errors/messages
return http.HttpResponse(json.dumps(self.response_data))
It also works great with signals since I always pass the view class to the signal. The signal can directly modify the instance error/message/data attributes, and the view will automatically format the data to our ajax format.
Access to the request object in class based view initialization
I was looking for a good place for the equivalent of __init__ with access to the request object that I could override. I found it in the dispatch method.
Since I generally don’t override it, it’s a great and DRY place for some base class code.
class CartBaseView(BaseView):
def get_cart_from_request(self, request):
# magically get cart
return magic_cart
def dispatch(self, request, *args, **kwargs):
self.cart = self.get_cart_from_request(request)
return super(CartBaseView, self).dispatch(request, *args, **kwargs)
class ViewCartView(CartBaseView):
def get(self, request):
print self.cart
# sweet!
def post(self, request):
print self.cart
Class based views are extremely powerful and I’m loving them.