If you have a model that has an "ordering" column, and you want to be able to re-position records (eg, order items by priority), this base class should make it fairly easy. To use it, you extend your model using this abstract class, then hook up the pre_save event to the pre_save event of the base class, and you're good to go. Whenever you save an item, it ensures that it has a valid "order" number. The meat of this class is the "move()" method. Just call instance.move(number) where instance is your model instance, and this class will do all the logic necessary to shift around the order numbers for you.
- sort
- order
- sortable
- orderable
- sorted
- ordered
Together with my mentor, Dusty Phillips, I have developed a simple class that dynamically adds two fields to its subclasses.
This is useful in cases when a single piece of content is divided into translatable and non-translatable fields, connected by a 1-to-many relationship.
## Update 2009/03/30
Since its inception, this snippet has grown into a significantly more powerful solution for translatable content (I use it myself with great joy :). The project is now hosted on github:
[project page](http://github.com/foxbunny/django-i18n-model/tree/master)
## Update 2008/07/09
It is now possible to define `i18n_common_model` attribute in `class Meta` section. Here's an example:
class Meta:
i18n_common_model = "MyCommonModel"
As you can see, it has to be a string, not the real class, and it is case-sensitive.
## Example
class Article(models.Model):
author = models.CharField(max_length = 40)
class Admin:
pass
class ArticleI18N(I18NModel):
title = models.CharField(max_length = 120)
body = models.TextField()
class Admin:
pass
# optionally, you can specify the base class
# if it doesn't follow the naming convention:
#
# class Meta:
# i18m_common_model = "Article"
When the ArticleI18N class is created, it automatically gains two new fields. `lang` field is a CharField with choices limited to either `settings.LANGUAGES` or `django.conf.global_settings.LANGUAGES`. The other field is `i18n_common` field which is a ForeignKey to Article model.
## The conventions
* call the translation model `SomeBaseModelI18N`, and the non-translation model SomeBaseModel (i.e., the translation model is called basename+"I18N")
* the first convention can be overriden by specifying the base model name using the `i18n_common_model` attribute in `Meta` section of the `I18N` model
* I18N model is a subclass of `I18NModel` class
## Original blog post
[http://blog.papa-studio.com/2008/07/04/metaclasses-and-translations/](http://blog.papa-studio.com/2008/07/04/metaclasses-and-translations/)
- models
- i18n
- metaclass
- translated-content
Somebody mentioned in #django the other day that they have multiple databases with the same schema... Well *lucky me* so do I!!
This is one way to work with this issue. I've also included migrate_table_structure just in case the schema doesn't exist in the new database yet.
As per the multiple-db-support branch, write all of your databases into the OTHER_DATABASES in settings.py. You can now copy models from your various models.py files and use them in different databases at the same time.
This can also be used to migrate databases from one dialect to the other without having to translate your data into an interim format (e.g. csv, XML). You can just do:
qs = MyModel.objects.filter(**filters)
NewModel = duplicate_model_and_rels(MyModel, 'new_db')
#Assuming that the schema is already in new_db:
for mod in qs:
new = NewModel()
new.__dict__ = mod.__dict__
new.save()
I tried this using some hacks with SQLAlchemy, and the above approach is a huge amount quicker! I've used this to copy some stuff from an oracle db, into a sqlite db so i could carry on working later and transferred about 20,000 in 5 mins or so.
GOTCHAS
========
This only works against my copy of multi-db as I've made a couple of changes. My copy is substantially the same as my patch attached to ticket 4747 though, so it might work to a point (especially the data migration aspect). If it doesn't work hit me up and I'll send you my patch against trunk.
I'm not too crazy about the code in copy_field, it works fine, but looks ugly... If anyone knows of a better way to achieve the same, please let me know.