When do we need class-based views in Django? - django

I'm learning Django and I've finished 2 tutorials - official and amazing tutorial called Tango With Django. Though, I got everything I need to work, I have one question:
In Tango with Django aren't used class-based views - only links to the official tutorial.
Why didn't they include this information?
When should we use class-based views and is it a good practice?

Class based views allow you to structure your views and reuse code by harnessing inheritance and mixins.
https://docs.djangoproject.com/en/1.8/topics/class-based-views/
For example you can inherit from "TemplateView" class which provides some features that you may need to use in your own view. For example you can reuse "get" method.
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"

We use class based views (CBV's) to reduce the amount of code required to do repetitive tasks such as rendering a form or a template, listing the items from a queryset etc.
Using CBV's drastically reduces the amount of code required and should be used where it can be.

It is good to be used in a CRM system. You have a a list view, item view, delete view etc, such as an blog. CBV could help you write less code.
But also because it has do too much for you. Sometimes it will be a little bit troublesome to make some customization or add some extra logic. In this situation, it is more suitable for those really experienced and familiar with CBV so that they could change it easily.

Related

How can I automate urls for django generic views?

I have subclassed Django's generic views for my project. I use them extensively to create basic CRUD views on our front-end site. Some models have just a create view, some have a read and update, etc.
This works well but I still write a line of code for each URL. ie:
url(r'^referrer/create/$',ReferrerCreateView.as_view(), name='referrer_create'),
url(r'^referrer/$',ReferrerListView.as_view(), name='referrer_list'),
url(r'^referrer/(?P<pk>\d+)/update/$',ReferrerUpdateView.as_view(),
name='referrer_update'),
I then do this for every model and the views that model has. This doesn't seem to be a very DRY approach to me. Is there a good approach to automating these urls for any generic view that has been created for a model?
The solution is to create a method that will return a list of url() calls given a set of views. Something like
views = {
'base_name': 'referrer',
'create_view': ReferrerCreateView,
'list_view': ReferrerListView,
'update_view': ReferrerUpdateView,
}
def generate_urls(views):
return [
url(r'^%s/create/$' % views['base_name'], views['create_view'].as_view(), '%s_create' % views['base_name'],
# and so on
]
Then you just need to do
urlpatterns = patterns('', *generate_urls(views))
For every set of views you have.
That being said I believe you shouldn't do this. This solution (or any different implementations) is over complicated and will add an extra layer you'll need to go through if things go wrong.
There's nothing wrong of having some boilerplate code, especially configuration code, because it makes your life much easier to debug in the future.
I have the same very concern and I shared it here before
One answer was the use of django rest framework as it implements such url patterns on its own!?! I didn't experience this solution yet.
My workaround is to have a dedicated file for crud operations for every model.
By that solution I decreased the matching time , and grouped related model pattern in one file.
BUT I understand that wont fully solve your question

Are Django's generic class views actually used?

I have discovered Django's generic class views now when I'm in the middle of my first Django project.
I didn't know that there are class based views or generic views.
I have made my own class views but now I'm thinking of refactoring. The only problem is I don't like these Django built-in views. I don't like putting stuff in the urls.py, my own views call sometimes each-other (they don't return a result, just add to the context)...
Anyway, I'm curios what others are doing? Are Django's built-in generic views actually used in real life?
mixins are a good way of using generic class based views.
here is a good comparison of the advantages and disadvantages of class based views

Django design patterns for overriding models

I'm working on an e-commerce framework for Django. The chief design goal is to provide the bare minimum functionality in terms of models and view, instead allowing the users of the library to extend or replace the components with their own.
The reasoning for this is that trying to develop a one-size-fits-all solution to e-commerce leads to overcomplicated code which is often far from optimal.
One approach to tackling this seems to be using inversion-of-control, either through Django's settings file or import hacks, but I've come up against a bit of a problem due to how Django registers its models.
The e-commerce framework provides a bunch of abstract models, as well as concrete versions in {app_label}/models.py. Views make use of Django's get_model(app_label,model) function to return the model class without having to hard-code the reference.
This approach has some problems:
Users have to mimic the structure of the framework's apps, ie the app_label and effectively replace our version of the app with their own
Because of the way the admin site works by looking for admin.py in each installed app, they have to mimic or explicitly import the framework's admin classes in order to use them. But by importing them, the register method gets called so they have to be unregistered if a user wants to customise them.
The user has to be extremely careful about how they import concrete models from the core framework. This is because Django's base model metaclass automatically registers a model with the app cache as soon as the class definition is read (ie upon __new__), and the first model registered with a specific label is the one you're stuck with. So you have to define all your override models BEFORE you import any of the core models. This means you end up with messy situations of having a bunch of imports at the bottom of your modules rather than the top.
My thinking is to go further down the inversion-of-control rabbit hole:
All references to core components (models, views, admin, etc) replaced with calls to an IoC container
For all the core (e-commerce framework) models, replace the use of Django's base model metaclass with one that doesn't automatically register the models, then have the container explicitly register them on startup.
My question:
Is there a better way to solve this problem? The goal is to make it easy to customise the framework and override functionality without having to learn lots of annoying tricks. The key seems to be with models and the admin site.
I appreciate that using an IoC container isn't a common pattern in the Django world, so I want to avoid it if possible, but it is seeming like the right solution.
Did you look at the code from other projects with a similar approach?
Not sure if this way covers your needs, but imo the code of django-shop is worth to look at.
This framework provides the basic logic, allowing you to provide custom logic where needed.
customize via models
eg see the productmodel.py
#==============================================================================
# Extensibility
#==============================================================================
PRODUCT_MODEL = getattr(settings, 'SHOP_PRODUCT_MODEL',
'shop.models.defaults.product.Product')
Product = load_class(PRODUCT_MODEL, 'SHOP_PRODUCT_MODEL')
customize via logic/urls
eg see the shop's simplevariation-plugin
It extends the cart-logic, so it hooks in via urlpattern:
(r'^shop/cart/', include(simplevariations_urls)),
(r'^shop/', include(shop_urls)),
and extends the views:
...
from shop.views.cart import CartDetails
class SimplevariationCartDetails(CartDetails):
"""Cart view that answers GET and POSTS request."""
...
The framework provides several points to hook-in, the simplevariation-plugin mentionned above additionally provides a cart-modifier:
SHOP_CART_MODIFIERS = [
...
'shop_simplevariations.cart_modifier.ProductOptionsModifier',
...
]
I worry that this explanation is not very understandable, it is difficult to briefly summarize this concept. But take a look at the django-shop project and some of its extensions: ecosystem

Django Generic Views, design guide

I accept that the question is a bit subjective, and that it does not pin point at certain technical doubt/query, but i wanted to know.
I am a newbie in django, after 3-4 months of doing apps in django i am trying to dig-down-deep.
I am currently reading a book by James Brennet where he shows how to use generic views, but when i head to https://docs.djangoproject.com/en/dev/topics/ i see generic views are depricated.
From the "best design perspective" point of view, how is using generic views rated?
Is it considered a good practice to use generic views?
If yes why is then django depricating it?
If no, what else is recommended?
Thanks!
The old generic views are deprecated because they've been replaced with 'Class-based generic views':
https://docs.djangoproject.com/en/dev/topics/class-based-views/
If you have a lot of view which repeatedly express the same pattern, for example a set of CReate/Update/Delete (CRUD) views for several models... where most of the view code is the same but just some specifics change, eg the model class and final redirect url... this is where generic views make sense.
The goal is to be DRY (Don't Repeat Yourself) ...ie write the code in one place and re-use, catch and fix bugs in one place etc.

Sharing view logic in Django

I've begun diving into Django again and I'm having trouble finding the parallel to some common concepts from my life in C#. While using .NET MVC I very often find myself creating a base controller which will provide a base action implementation to take care of the type of stuff I want to do on every request, like retrieving user information, getting localization values.
Where I'm finding myself confused is how to do this in Django. I am getting more familiar with the MVT concept but I can't seem to find how to solve this scenario. I've looked at class based views and the generic views yet they didn't seem to work how I expected. What am I missing? How can i create default logic that each view will be instructed to run but not have to write it in each view method?
If it is truly common for your whole site you use middleware. If it is only common for some views, the way to go in my opinion is to create decorators for those views. I never use class-based views because I tend to keep views simple and put more logic into models, so I have no need for classes there.