Using classes for Django views, is it Pythonic? - python

I'm currently learning Python and coming from a strong C# background. I keep hearing about doing things in a Pythonic way to take advantage of the dynamic nature of the language and some of it I get and some I don't.
I'm creating a site with Django and my approach to views is to use classes. My current thinking is to have a base class that has some stuff about the template and the model to use. This will have a default funky 404 type page with site search and stuff on then base all the other pages off this. So each area of the site will have its own EG News and all the model related functions and filtering will be in that class with a further class on top of that for HTML or AJAX requests. So you would have something like this:
\site\common\ViewBase
--\news\NewsBase(ViewBase)
--\news\HtmlView(NewsBase)
--\news\AJAXView(NewsBase)
URLs would be mapped like http://tld/news/latest maps to site.news.htmlview and http://tld/news//to/ will be also be mapped site.news.htmlview but the class will figure out what to do with the extra params.
This is pretty much what I would do in C# but the Django tutorial only shows using methods for views, making me wonder if this is not a very pythonic solution?
Thoughts?
Edit: After S.Lott comment about thread safety, Is it better to leave the functions as they are and have them create an instance of a class and call a method on it?
What I am looking for is a place to put common code for each section of the site for filtering the model, authentication for the site, etc

Certainly there's nothing wrong with using a class for a view, provided you route the URL to an actual instance of a class and not just a class directly.

The Django admin does exactly this - look at the source code in django/contrib/admin.
The advantage of classes is that they are much easier to customize, for example you can add hooks for permission checking.
There is a proposal to move all existing generic views over to classes, it was supposed to get into 1.2 but failed to meet the deadline.
As the above poster points out, be very careful about handling instance variables - if you look at the admin classes, you see the request being passed to the various methods instead of relying on "self".

Setting aside other concerns (such as thread-safety issues), it feels like there's a real possible danger here to cross the bright lines between Model / View / Template.
Or maybe it feels like a replacement for url dispatching (not that there's anything wrong with that :-). I'm not sure, but it just feels slightly off.

While class-based views are useful, inheritance may not be the right tool for this particular job. Helper functions and decorators are two great ways to factor out common code from your views. They also tend to be be more familiar/natural to other (python) coders who might work on your code.
I'm not sure what the best approach is in your case as I don't know how much you ultimately want to factor, just keep in mind that there are other ways to factor in python besides inheritance.
p.s. kudos for seeking out a pythonic solution.

Related

Are class based views widely used by the Django community?

I am new to Django and Python and after reading a lot I decided not to use global functions as views (maybe because I am not used to global functions but mostly because I want a better reuse level and prefer to have smaller code blocks). The problem is that most of the Django apps I have been checking do not use a class based approach.
Is this because I am checking code in the wrong places (I started with the Django tutorial and then on github)?
I'm asking this because in the future I hope to be working with more Django programmers and don't want to adopt a non-standard approach at the beginning.
One fact is that class based view was added in Django 1.3, so if you're planning to support old Django version than you will have to stick with function view, for example if you want to create a generic app and launch it in GitHub or such for other people to use.
As for when to use class based view over function view i think this will depend on your use case, my advice is that you have to understand the advantage of each way, and IMHO it's pretty normal to have both implementation in a single project.
There was this nice article of Nick Coghlan on response to another great article CBV were a mistake that it worth to check.
Hope this was helpful :)

Is it safe to access ._meta directly in your django app?

Django uses Meta class for lots of additional object information. However, they store this information in an object '_meta' which by naming convention is private.
All over the django admin (and other places) I see stuff like opts = model._meta and then they use the various options like app_label and verbose_name.
Can I be confident accessing ._meta and be sure that it will not change in the future, or am I better off creating one 'accessor' mixin or something that accesses the ._meta in one spot, so if it ever does change I only have to update one thing?
I use _meta frequently and haven't had any issues so far. You can see in the django documentation an example of them using it too here, so I have felt its more or less ok to do. Just tread carefully and write good tests so you know of any problems when you upgrade your django version later on down the road.
I use _meta in several projects where I want to have generic access to information that's otherwise not provided by the api. I think you're probably okay most of the time as Django is pretty stable. It's probably a good idea to be covering your usage of _meta in your unit tests.

RESTful APIs for Django projects/apps

What do you prefer when you want to "RESTify" your Django project in Django?
I came to the conclusion that there are really three options to do that:
django-piston http://bitbucket.org/jespern/django-piston/wiki/Home
django-rest-interface http://code.google.com/p/django-rest-interface/
django-restful-resources http://watchitlater.com/blog/2010/02/django-restful-resources/
Right way to do this for me would be to try all of'em and pick the one that is best for me, so meanwhile I'd like to hear yours...
Thanks.
I'm most familiar with django-piston, so I would naturally steer you in that direction.
A quick glance at the other two, though, indicates that django-rest-interface does nothing more than expose models as resources, and that django-restful-resources is some guy's one-off attempt at the same.
Piston, if I recall correctly, grew out of bitbucket.org's own site development, and allows a lot of flexibility - you can return almost any object from your resource's access methods, not just model instances, and it will be properly encoded. It also has built-in support for some nice features, like form validation (if you can get it to work right, anyway) and request throttling, among other things.
With the new class-based generic views in django 1.3 it will be super-easy to implement your own rest interface, with custom serializers and deserializers, replicating the almost complete piston's implementation using just stock code. I made a View(1.3)-based rest module in 500 lines of code, with generic RESTful resource class and sub resources, natural key support for associations, json and XML serialization and more. the module is really tailored upon my app's requirements
I did it to overcome a couple of limitations in piston's code, like having a query set modified (e.g. With .values(...)) before the handler calling .get() on it, or not being able to use a model's method in serialization.
If you do it as you need it, in a couple of days you'll have a working set of classes and mixins, that you will fully understand and be in control of.
As the "some guy" who wrote django-restful-resources I would like to clarify why it exists. It is NOT an attempt to expose models as resources, rather it is a means of allowing a single URL to be mapped to a number of different handler methods, one per HTTP verb. That's all. It can be used to expose model objects, but it can also be used to expose services as resources or anything else that you want to interact with via a single URL and HTTP verbs. If you are looking for a more full-featured solution then by all means go with Piston.
As mentioned by eternicode, django-piston is excellent. It's mature, well featured and has a good community behind it. It does seem to be lacking much ongoing development at the moment, although there is talk of a community driven fork, so that may change.
django-tastypie is also well worth a look, and seems to have a lot of impetus behind it at the moment.
I've also just released another option that's worth considering: django-rest-framework. There's a couple of really nice features behind it such as the API auto-documentation.
It uses Django 1.3's class based views, as mentioned by saverio, which means you can just drop in some of the MixIn classes it provides, without having to use the framework outright. (For example adding HTTP content negotiation for serializing output to multiple types)

Django web interface components

I am using python and django and like it a lot. But than i use it, I catch myself thinking
what i do a lot of work to render result data and write specific actions for it. For example than i pass result set of objects to template
i must render all data and write all possible actions such as sorting by columns,filtering,deletion,edit etc, for each of this i need
to write code in urls.py and views.py, sometimes helps generic view but it's has poor functions.
Is there some solutions to automate this work?
i mean use some interface compontents (such as "model list renderer with column filter and pagination") to wich i need only
"bind my model", all other routing work for drawing common interface action must be allready implemented in these components.
i think i need something like configurable components for fast building html web interface for models (such as model forms do fast generation forms for models).
What do you think can help in this case?
must render all data and write all
possible actions such as sorting by
columns,filtering,deletion,edit etc
Like django.contrib.admin? But I guess it's way to complicated and bloated for your needs.
sometimes helps generic view but it's
has poor functions
And that's the way, I think, you should be going. If you write same views over and over again, just make your own generic views. As an example of more robust views and a source of inspiration I recommend you to look at class-based generic views.
Also consider using model inheritance and custom managers.

MVC and django fundamentals

Pretty new to this scene and trying to find some documentation to adopt best practices. We're building a fairly large content site which will consist of various media catalogs and I'm trying to find some comparable data / architectural models so that we can get a better idea of the approach we should use using a framework we've never made use of before. Any insight / help would be greatly appreciated!
"data / architectural models so that we can get a better idea of the approach we should use using a framework we've never made use of before"
Django imposes best practices on you. You don't have a lot of choices and can't make a lot of mistakes.
MVC (while a noble aspiration) is implemented as follows:
Data is defined in "models.py" files using the Django ORM models.
urls.py file maps URL to view function. Pick your URL's wisely.
View function does all processing, making use of models and methods in models
Presentation (via HTML templates) invoked by View function. Essentially no processing can be done in presentation, just lightweight iteration and decision-making
The model is defined for you. Just stick to what Django does naturally and you'll be happy.
Architecturally, you usually have a stack like this.
Apache does two things.
serves static content directly and immediately
hands dynamic URL to Django (via mod_python, mod_wsgi or mod_fastcgi). Django apps map URL to view functions (which access to database (via ORM/model) and display via templates.
Database used by Django view functions.
The architecture is well-defined for you. Just stick to what Django does naturally and you'll be happy.
Feel free to read the Django documentation. It's excellent; perhaps the best there is.
first, forget all MVC mantra. it's important to have a good layered structure, but MVC (as defined originally) isn't one, it was a modular structure, where each GUI module is split in these tree submodules. nothing to use on the web here.
in web development, it really pays to have a layered structure, where the most important layer is the storage/modelling one, which came to be called model layer. on top of that, you need a few other layers but they're really not anything like views and controllers in the GUI world.
the Django layers are roughly:
storage/modelling: models.py, obviously. try to put most of the 'working' concepts there. all the relationships, all the operations should be implemented here.
dispatching: mostly in urls.py. here you turn your URL scheme into code paths. think of it like a big switch() statement. try hard to have readable URLs, which map into user intentions. it will help a lot to add new functionality, or new ways to do the same things (like an AJAX UI later).
gathering: mostly the view functions, both yours and the prebuilt generic views. here you simply gather all the from the models to satisfy a user request. in surprisingly many cases, it just have to pick a single model instance, and everything else can be retrieved from relationships. for these URLs, a generic view is enough.
presentation: the templates. if the view gives you the data you need, it's simple enough to turn it into a webpage. it's here where you'll thank that the model classes have good accessors to get any kind of relevant data from any given instance.
To understand django fundementals and the django take on MVC, consult the following:
http://www.djangobook.com/
As a starting point to getting your hands dirty with ...
"...trying to find some comparable data / architectural models"
Here is a quick and dirty way to reverse engineer a database to get a models.py file,
which you can then inspect to see how django would handle it.
1.) get an er diagram that closely matches your target. For example something like this
http://www.databaseanswers.org/data_models/product_catalogs/index.htm
2.) create an sql script from the er diagram and create the database,
I suggest Postgre, as some MySQL
table type will not have forgien key constraints, but in a pinch MySQL or SQLITE
will do
3.) create and configure a django app to use that database. Then run:
python manage.py inspectdb
This will at least give you a models.py file which you can read to see how django attempts
to model it.
Note that the inspect command is intended to be a shortcut for dealing with legacy
database when developing in django, and as such is not perfect. Be sure to read the
following before attempting this:
http://docs.djangoproject.com/en/dev/ref/django-admin/#ref-django-admin

Categories

Resources