tag: django

  • Type Polymorphism in Django

    View Comments

    Monday, May 24, 2010 11:15 p.m.

    models.py

    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes import generic
    
    related_object_limits = {'model__in': ('specificitem1', \
        'specificitem2')}
    
    class RelatedItem(models.Model):
    
        content_type = models.ForeignKey(ContentType, \
            related_name='main_object', \ 
            limit_choices_to=related_object_limits)
        object_id = models.PositiveIntegerField()
        content_object = \
            generic.GenericForeignKey('content_type', \
            'object_id')
    
        related_content_type = \
            models.ForeignKey(ContentType, \
            related_name='related_object', \
            limit_choices_to=related_object_limits)
        related_object_id = models.PositiveIntegerField()
        related_object = \
            generic.GenericForeignKey('related_content_type', \
            'related_object_id')
    
    class Item(models.Model):
    
        name = models.CharField(max_length=100)
        slug = models.SlugField(unique=True)
        related = generic.GenericRelation(RelatedItem, \
            content_type_field='content_type', \
            object_id_field='object_id')
    
        def __unicode__(self):
            return self.name
    
        class Meta:
            abstract = True
    
    class SpecificItem1(Item):
        property1 = models.CharField(max_length=100)
    
    class SpecificItem2(Item):
        property2 = models.CharField(max_length=100)
    

    admin.py

    from django.contrib import admin
    from django.contrib.contenttypes.generic \
            import GenericTabularInline
    
    from models import SpecificItem1
    
    class RelatedItemInline(GenericTabularInline):
        model = RelatedItem
    
    class SpecificItem1Admin(admin.ModelAdmin):
        list_display = ('name', 'slug')
        search_fields = ('name',)
        inlines = [RelatedItemInline,]
    
    admin.site.register(SpecificItem1, SpecificItem1Admin)
    

    Some ideas on how to get the admin playing nice.

    permalink | tagged as: django polymorphism

  • Migrating a Django Project from SQLite to MySQL / PostgreSQL

    View Comments

    Tuesday, February 23, 2010 midnight

    Should you ever be tasked with migrating a django project running on an sqlite database to postgresql or mysql, the following are some of the steps I took.

    The project was already in production, so I needed all the data to come along with it. This caused some problems that django, sadly, wasn’t equipped to handle.

    ./manage.py dumpdata > mydumpfile.json
    
    ./manage.py dumpdata --indent=n > mydumpfileindent.json
    
    grep myword mydumpfileindent.json
    grep -A 10 -B 10 -n myword mydumpfileindent.json
    
    mysql -u root -p
    
    mysql> drop database dbname;
    mysql> create database dbname
        -> character set utf8 collate utf8_general_ci;
    mysql> grant all on dbname.* to dbuser@localhost
        -> identified by dbpass;
    mysql> exit;
    
    sudo -u postgres dropdb dbname;
    sudo -u postgres createdb dbname -E utf8 -O dbuser;
    
    ./manage.py syncdb
    
    ./manage.py sqlflush | mysql -u dbuser -p dbname
    
    ./manage.py sqlflush | sudo -u postgre psql dbname
    
    mysql -u dbuser -p dbname
    
    mysql> alter table tablename modify 
        -> columnname columntype;
    
    mysql> alter table tablename add
        -> columnname columntype after othercolumn;
    
    ./manage.py loaddata mydumpfile.json
    

    django-command-extensions

    osx utilities:

    permalink | tagged as: migration osx django postgresql mysql sqlite

  • Multilingual Site w/ Django

    View Comments

    Saturday, October 17, 2009 10:34 p.m.

    A brief tutorial on how I setup a multilingual website using django. Be forewarned, this is a pretty rough draft. I will hopefully get some time to go over it. If you have any questions, contact me.

    This tutorial is for translating your site based on the url you are accessing. In other words, /en/ for English, /fr/ for French, or /language_code/ for any language of your choice. However, most of the following is applicable for use with the proper state change by post method of translating the site.

    I’ll assume that you’ve got python / django up and running on your system and we can just begin with a django-admin.py startproject my_multi_site.

    There’s a few things that need to be setup in your settings.py file. Open that up and under LANGUAGE_CODE that should be defaulted to 'en-us', add these lines:

    _ = lambda s: s
    
    LANGUAGES = (
        ('en', _('English')),
        ('fr', _('Français')),
    )
    

    We’ve defined a dummy function for the language strings as suggested in the internationalization docs. You can obviously set any languages you’ll need, just make sure that the language you want as your default comes first in the list.

    The one stumper here is that I’ve added a UTF-8 character ( ç in Français ) in the settings file, which it complains about. Be sure to save the file w/ UTF-8 encoding. For those of you using Vim, like me, I was able to do this by adding # vim: set fileencoding=utf-8 : at the top of my file ( # vim: set encoding=utf-8 : seems to work on another system ). I went through this trouble, rather that just writing French, because I use the LANGUAGES list on my homepage and in the admin, and I want to use that spelling.

    Next, make sure USE_I18N = True which it should be by default. You’ll also need the context processor django.core.context_processors.i18n which, again, is there by default. Actually, by default, TEMPLATE_CONTEXT_PROCESSORS is missing from your settings.py file, meaning that you’d have to go out of your way to remove i18n support.

    The last piece in the settings.py, for now, is to add django.middleware.locale.LocaleMiddleware to your MIDDLEWARE_CLASSES.

    At this point in the docs, the suggestion is to add (r'^i18n/', include('django.conf.urls.i18n')), to your urls, and then you can post a form to /i18n/setlang/ with a ‘language’ var containing the language code you want to set and a ‘next’ var to where the page should redirect. Properly, you should only change the state of your site with a post. However, I would like to set the site language based on the url. In other words, /en/ for English, /fr/ for French.

    Because this behaviour is frowned upon, we’ll have to collect a django snippet to get it done. This snippet makes reference to an unknown CULTURES setting so I hacked it up to use the LANGUAGES we defined above. Place that package on your PYTHONPATH and add the middleware to your settings file. It should look something like i18nmiddleware.i18n.I18nUrlsMiddleware, following directory.file.class.

    Now, you’ll probably have noticed in the i18n.py file you downloaded above, that there’s a section to be lifted in it for your urls. It should look like url(r'(?P<dj_culture>[\w-]+)/', direct_to_template, {'template' : 'intro.html'}, name="intro"),. Be sure to put your admin url string above that. If you create an intro.html template and place links in it to /en/ and /fr/, you should be able to alter your language by accessing those urls. You can expose {{ LANGUAGE_CODE }} in your template to see if its working.

    We can now try a few translations. First, in your template, place {% load i18n %}. The template tag to wrap words to translate looks like this: {% trans "translate this text" %}. Scatter a few of those around your page and then jump back onto the command line. In order to create the .po file that django uses for the translations, I had to install gettext. I’m running Mac OS X, and for my package installer, I use homebrew. So, a quick brew install gettext got that going. Now, you’ll need to create .po files for each language ( not the default, en ) specified in your settings file. You can break things down by project, app, or all of django if you’re using a language not yet supported by django. Since django is already translated into French, I just ran this command from the root of my project django-admin.py makemessages -l fr. The “fr” being the language code for French. It asks that you create a directory called “locale” beforehand. This goes through all the .html files in your project and creates a .po file for you to enter your translations. The .po files lives in locale/fr/LC_MESSAGES/. Once you’ve entered all your translations in the .po file, compile it with django-admin.py compliemessages. You can always reexamine your files for any changes with django-admin.py makemessages -a. Now, refreshing your site with the above language switcher should translate your pages.

    If everything’s working, we can move on to your models. …


    Edit: You probably want to check out django-localeurl instead of the above mess.

    permalink | tagged as: i18n multilingual django