Expando Model in Django - django

Is it possible to implement 'expando' model in Django, much like Google App Engine has? I found a django app named django-expando on github but it's still in early phase.

It's possible, but it would be a kludge of epic proportions. GAE uses a different database design known as a column-based database, and the Django ORM is designed to link with relational databases. Since technically everything in GAE is stored in one really big table with no schema (that's why you don't have to syncdb for GAE applications), adding arbitrary fields is easy. With relational databases, where each table stores exactly one kind of data (generally) and has a fixed schema, arbitrary fields aren't so easy.
One possible way you could implement this is to create a new model or table for expando properties that stores a table name, object ID, and a TextField for pickled data, and then have all expando models inherit from a subclass that overrides the __setattr__ and __getattr__ methods that will automatically create a new row in this table. However, there are a few major problems with this:
First off, it's a cheap hack and is contrary to the principles of relational databases.
Second, it is not possible to query these expando fields without even more hacks, and even so it would be ludicrously slow.
My recommendation is to find a way to design your database structure so that you don't need expando models.

Related

Why there isn't a "ListField" in Django?

I have a model that has a Charfield (let's name it advantages) with a choices attribute. After a while, I've decided that this field should be "upgraded" to some kind of ListField, since more than one choice can be selected.
From what I have searched, I have two options:
1 - Create a new model, and use a ManyToManyField in the first model referencing this new model. This way, the "multiple select" default field used in admin will be rendered. Life is good.
2- Create a custom field that saves my field as a string with some kind of separator.
These two approaches are summarized in What is the most efficent way to store a list in the Django models? and the 2nd approach in more examples: How to create list field in django, http://cramer.io/2008/08/08/custom-fields-in-django/, https://djangosnippets.org/snippets/1200/, https://djangosnippets.org/snippets/1491/
Fact is: I don't want to create another model just to have the ManyToManyField. This is a controlled list of choices that I have (and don't want people adding new items) and think that creating a table for this is overkill (although I can create a fixture to this table and not register the model in admin.py, so people wouldn't be adding new items. But I don't know how would migrations work when changing these values in fixtures, when in the past I would just chance the choices tuple in my model definition).
...and creating a new custom field, I don't know. This seems like problems in the long run since I don't know the implications, problems when upgrading Django, etc.
Why there isn't a built in ListField? Which problems do you see in the long run for the two approaches I'm thinking of? I'm planning to do the first but I'm a little lost about migrations.
django.contrib.postgres has an ArrayField.
You seem to not be willing to create a new table with only the List inside (because it would be "overkill"), but what you are suggesting is to copy/paste the same exact values in all the entries of your table, which isn't a good model solution in my opinion.
I'd advise to go for the ManyToMany (or any other implementation doing the trick with another table).

Django -- add model to database without losing data

I have a simple Django website (just a form, really) which asks a few questions and saves the data in a SQL database using Model.save(). Pretty simple. I want to add a model to do page counting, though -- it'll just be a single object with a field that gets incremented each time the page's view function is called.
Now, I know little to nothing about SQL. I imagine this is not terribly difficult to do, but I would like to avoid losing or breaking all my data because of a slight misunderstanding of how the database works. So how can I go about doing this? I've heard of some third-party apps that will implement such functionality, but I'd like to do it myself just for learning purposes.
I don't understand why your existing data would be affected at all. You're talking about adding a completely new table to the database, which is supported within Django by simply running manage.py syncdb. The case where that doesn't work is when you're modifying existing tables, but you're not doing that here.
I must say though that learning and using South would be of benefit in any case. It's good practice to have a tool that can maintain your model tables.
(Plus, of course, you would never lose any data, because your database is backed up, right? Right?)
Since you're adding new model, you can just run syncdb and it will create new table for your model. If you were to change existing model, then you'd need to manually update database schema using "ALTER TABLE" statements or use South instead.

Django end-user defined fields, how to? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Django dynamic model fields
Good Morning guys!
Scenario is the following. For some models on Django, I would like to allow the end user to define his own fields. It would be great if I could keep all Django awesome features like the ORM, so I can still do calls like field__gte to search on the model, still have field validation according to field type, etc. I've thought about two ways of doing this, and I'm more than open for new suggestions. Any feedback would be VERY appreciated.
The first approach, is the Entity-Attribute-Value ( http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model ), which django already has an app for. See http://code.google.com/p/django-custom-field/
I think this would be an OK solution, but I lose the ability to do "mymodel.objects.filter(custom_field_x=something)". Maybe there's a way to regain the ORM, any ideas? But I've heard so many bad stories about this method that I'm little scared to use it.
The second approach would be to have a database table for each of the users (probably no more than a 1000). I've read django has something in the lines of inspectdb, which actually checks which fields are there and produces the model for you. This could be useful but I think maybe I should store the fields this particular user has created and somehow dinamically tell django, hey, we also have this fields in this model. Is this possible? I know it's generally bad to have different tables for each user, but considering this scenario, how would you guys rate this method, would it be ok to have one table for each user?
The model that requires custom fields is for example Person. They might want a custom field to store address, blood type, or any other thing.
MANY THANKS in advance! Have a nice sunday!
Very similar: How to create user defined fields in Django -- but only talks about the EAV, which I would like to avoid. I'm open for new ideas!
One approach is to use a NoSQL document-based solution such as MongoDB which allows you to store objects that have a fluid structure (no such restrictions as pre-defined columns).
Pros:
No restriction on custom field types, number of types of fields, etc.
Retains ORM functionality (django-mongodb)
Other various benefits of NoSQL - which you can read about online
Avoids EAV
Cons:
Need to setup NoSQL server
Additional knowledge required on NoSQL concepts (documents vs. tables)
You may have to maintain two databases - if you decide not to migrate your entire solution to NoSQL (multi-db)
EDIT:
After reading the comments its worth pointing out that depending on which NoSQL solution you go with, you may not need reversion support. CouchDB, for example has built in support for document versioning.
what about creating another model for storing user_defined_fields?
class UserDefinedField(models.Model):
#..................
user = models.ForeignKey(User)
field_name = models.CharField(max_length=50)
field_value = models.TextField()
Then you can do UserDefinedField.objects.filter(field_name=some_name,field_value=somevalue)

How do I make changes to a model in Django?

How does Django handle changes to my Model? Or, what help does it offer me to do this?
I am thinking of a situation where I have already have published data to my DB which I don't want to lose, but I need to make changes to my data model - for example, adding extra fields to a particular class, changing the types of fields, etc. My understanding is that syncdb won't ever alter tables that already exist in the DB.
For example, let's say I have the following model:
class Person(models.Model):
name = models.CharField(max_length=200)
phone_number=models.CharField(max_length=200)
hair_colour=CharField(max_length=50)
Things I might want to do to Person off the top of my head:
I wish to add an 'age' field.
I realise I want to use IntegerField instead of CharField for phone_number (whether this is a good idea or not, is out of scope...) - assuming it's possible.
I realise that I no longer wish to define hair_colour 'inline' within Person, because several people share the same hair colour - I wish instead to change this to be a foreign key to some other model.
Whilst I can imagine some of these are tough/impossible for the framework to 'guess' exactly what needs to be done to my data if all I do is update the models.py, I can imagine that there might still be some tooling to help enable it - does it exist?
In particular I imagine there must be some good patterns for option 1.
I'm very new to Django and have no experience with any other ORM-type stuff, which I think this is - I've always been a bit suspicious of ORMs, mainly for the reasons above :)
Django itself will not attempt to modify an already created database table. What you are trying to do is typically called "Migration" and there are a couple of different Database Migration tools available for Django.
South
Schema Migrations
Data Migrations
Backwards Migrations
Nash Vegas
Schema Migrations
Data Migrations
Django Evolution
Schema Migrations
Data Migrations (Unknown)
Backwards Migrations (Unknown)
Of the three South is probably the most widely used but they each have different ways of dealing with migrations. You can see more details on the comparison on Django Packages.
Much of what you're asking about can be done with the django project South. You add it as an INSTALLED_APP. Create a baseline, then as your model changes it creates SQL statements to convert your tables and the rows with-in the tables to the new model format.

Understanding Django's Intermediary Models

I'm trying to understand the purpose of Django Intermediary Models.
Conceptually, they seem to be equivalent to association classes in UML class diagrams. Is there any fundamental difference between the two that I should be aware of?
In spite of the apparent similarity, I've found several resources explaining the purpose of intermediary models, but none of them made any reference to "association classes", which makes me somewhat suspicious.
You're not likely to find any comparisons with UML diagrams in the Django literature - UML modelling isn't really a big thing in the Python world, in my experience.
But looking at your diagram, I'd agree that the concept does seem very similar. Don't forget that the ORM is just that, a mapping of relational concepts onto objects: in this case, the through table maps the intermediary table that is always created in a many-to-many relationship. The only difference is that you only need to specify it manually if you want to add extra information to that relationship, like the enrollment date in your link. If you don't need the extra fields, you don't need to specify the intermediary model, but the table still exists, containing just the foreign keys to each end of the M2M relationship.
They're used to store additional data about a many-to-many relationship. I'm sure this is blasphemy, but I think the best example is from the Ruby on Rails guides, which uses the association between patients and doctors. A doctor has many patients through appointments; a patient has many doctors through appointments as well; but you can't model this relationship directly, because an appointment also has a date and time.
I think you are right that conceptually, they server a similar purpose to association classes in UML.
This is how many-to-many relation is to be implemented in any relational database, it is a fundamental part of relational database design. So I suggest to learn about database design principles first because knowing how database works is necessary for using ORM properly anyway.
wikipedia on Many-to-many