*I suppose I'm kind of stubborn, but I prefer to use underscores to replace spaces and other characters. Of course, that shouldn't hold you back from using the build-in slugify filter :)*
** Forcing the slug to use ASCII equivalents: **
Transforming titles like "Äës" to slugs like "aes" was kind of a trial and error job. It now works for me. I hope `_string_to_slug(s):` proves a rather stable solution. Yet the worst-case scenario is that such characters are lost, I guess that is acceptable.
Other ways of dealing with this problem can be found at [Latin1 to ASCII at Activestate](http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/251871) or in the comments below.
**How to use:**
The slug fields in your model must have prepopulate_from set, the fields specified in it are used to build the slug.
To prevent duplicates, a number is added to the slug if the slug already exists for the current field in another, previous, object. I guess there should be a cleaner way to distinguish between creating a new db entry or updating an existing one, sadly, the db back-end is kind of a black-box to me. At least this works ;)
I choose not to alter the slug on an update to keep urls more bookmarkable. You could even extend this further by only updating the slug field if it hasn't been assigned a value.
The snippet enables decoupling model classes, associated with a ForeignKey, for the purpose of separating them into two databases. Looking at the following example:
class Reporter(models.Model):
...
class Article(models.Model):
reporter = models.ForeignKey(Reporter)
We want to separate the `Reporter` and `Article` into two separate databases, but this won't work in Django because of the [cross model relations](http://docs.djangoproject.com/en/dev/topics/db/multi-db/#cross-database-relations). The solution is to use an ID field and not a `ForeignKey` one. This makes the access very uncomfortable. The above class will make this a bit less awkward. It doesn't support the [RelatedManager](http://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager), but it will support accessing the related field as you normally would.
The article class will look like this (assuming the reporter model id field is an `IntegerField`):
class Article(DecoupledModel):
reporter_id = models.IntegerField()
_linked_fields = {
'reporter': Reporter,
}
Once you have an article object, you can access the reporter as you normally would for both read and writing. For example:
my_reporter = article1.reporter
article2.reporter = my_reporter