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.
Related
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 :)
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.
I've written some python code to accomplish a task. Currently, there are 4-5 classes that I'm storing in separate files. I'd now like to change this whole thing into a database-backed web app. I've been reading tutorials on Django, and so far I get the impression that I'll need to manually specify the fields and their types for every "model" that I use. This is a little surprising to me, since I was expecting some kind of ORM capability that would just take the existing classes I've already defined, and map them onto a database somehow, in a manner abstracted away from me.
Is this not the case? Am I missing something? It looks like I need to specify all the fields and types in the file 'models.py'.
Okay, now beyond those specifics, does anyone have any general tips on the best way to migrate an object-oriented desktop application to a web application?
Thanks!
That is Django's ORM: it maps classes to tables. What else did you expect? There needs to be some way of specifying what the fields are, though, before you can use them, and that's managed through the models.Model class and the various models.Field subclasses. You can certainly use your classes as mixins in order to use the existing business logic on top of the field definitions.
If you are thinking about a database backend based web app, you have to specify what fields of the data you want to store and what type of the value you want stored.
There is an abstraction that introspects the db to convert it into the django models.py format. But I know not of any that introspects a python class and stores arbitrary data into db. How would that even work? Are the objects, now, stored as a pickle?
You're going to have to check the output, but you can have Django automatically create models from existing databases through one-time introspection.
Taken from the link below, you would set up your database in settings.py, and then call
python manage.py inspectdb
This will dump the sample models.py file to standard out for your inspection. In order to create the file, simply redirect the output
python manage.py inspectdb > models.py
See for more:
http://docs.djangoproject.com/en/dev/howto/legacy-databases/?from=olddocs#auto-generate-the-models
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)
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