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.
Makes a call to Google's geocoder and returns the latitude and longitude as a string or returns an empty string. Called by the save method to save the lat and long to the db to be used when rendering maps on the frontend. Reduces the number of calls to geocoder by calling only when saving, not on every viewing of the object.
Be sure to import *urllib* and the project's *settings*, and to define GOOGLE_API_KEY in settings.py.
**Example:**
def save(self):
location = "%s+%s+%s+%s" % (self.address, self.city, self.state, self.zip_code)
self.lat_long = get_lat_long(location)
if not self.lat_long:
location = "%s+%s+%s" % (self.city, self.state, self.zip_code)
self.lat_long = get_lat_long(location)
super(Foo, self).save()
- google-maps
- geocode
- google-api
- latitude
- longitude