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

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.

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 :)

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)

How about having a SingletonModel in Django?

I'm making a very simple website in Django. On one of the pages there is a vertical ticker box. I need to give the client a way to edit the contents of the ticker box as an HTMLField.
The first way that came to mind was to make a model Ticker which will have only one instance. Then I thought, instead of making sure manually that only one instance exists, perhaps there is (or there should be) something like a SingletonModel class in Django, which is like a normal model, except it makes sure no more than one instance gets created?
Or perhaps I should be solving my problem in a different way?
Try django-solo, it works in django 1.5 + for sure, django-singletons doesn't work with 1.5 + because it uses a deprecated feature.
You can use django_singletons. It has a built in admin support.
I think having a "singleton" model is ugly; it's dumb use of the relational database and it's bad UI, because the admin UI is built around working with lists of objects.
Instead I prefer to use a generic solution like django-chunks or django-flatblocks for this.
rewrite your save method so that every time a Ticker object gets saved it overwrites the existing one (if one exists).
A model with only one instance, a singleton, is sometime useful for things like global settings that you want to edit from the admin instead of having them in Django settings.py.
There are several third party applications that helps implementing singleton models and improve the admin interface for instance, django-solo, django-singleton-admin, django-singletons.

Django and monkey patching issue

I have recently started experimenting with Django for some web applications in my spare time. While designing the data model for one, I came across the dilemma of using inheritance to define a user of the website or using a technique known as monkey patching with the User class already supplied by the framework.
I tried to add a field by means of (after having defined all my models etc. without errors, according to python manage.py validate):
User.add_to_class('location', models.CharField(max_length=250,blank=True))
and executed the syncdb command. However, I keep getting this error
OperationalError: no such column:
auth_user.location
whether I am in the admin view of the site or the manage.py shell. There must be an extra step I'm missing, but there seems to be limited documentation on the whole monkey patching technique. So I'm asking you for assistance before I resort to inheritance. Any code, tips, or pointers to additional documentation are of course welcome.
Thanks in advance.
PS. I'm aware this technique is ugly, and probably ill-advised. ;)
There's an alternative to both approaches, which is to simply use a related profile model. This also happens to be a well-documented, highly recommended approach. Perhaps the reason that the add_to_class approach is not well-documented, as you noted, is because it's explicitly discouraged (for good reason).
When you add a field to any model, even if you do it the 'official' way, you need to migrate the database - Django doesn't do it for you. Drop the table and run ./manage.py syncdb again.
You might want to investigate one of the migrations frameworks, such as south, which will manage this sort of thing for you.
Here's a (slightly older) way of extending the User model.
Here's what the docs have to say.
And here's a recent conversation on django-users about the topic.
Djangos framework uses metaclasses to initialize the tables. That means you can't monkey-patch in new columns, unless you also re-initialize the class, which I'm not sure is even possible. (It may be).
See Difference between returning modified class and using type() for some more info.
I guess you might run into problems regarding where is your monkeypatch defined. I guess django syncdb creates databse tables only from the "pure" auth application, so your model will then be without "location", and then your site with the patch will look for the field.
Probably less painful way of adding additional info to user profiles is described in Django docs.

Using classes for Django views, is it Pythonic?

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.

Categories

Resources