Dynamic Translation Apps for Django
When I needed multi-language flatpages and flatblocks for telvee I searched for available Django apps that do dynamic translation. By dynamic translation, I mean translations are entered and stored in the database. As I said I needed to be able to translate both full pages and chunks of text that I can include into another page. I ended up rolling my own, which is without a doubt lesser to some apps below. I will try to imrove it with the good ideas from existing projects and then open source. Meanwhile I would like to share my review of 6 dynamic translation apps with you. I hope someone out there finds it useful.
Django-multilingual
One of the few active projects I have reviewed is django-multilingual. To enable a model for translations you need to create a Translation inner-class and move translatable fields inside. Then a seperate model for those fields is created behind the scenes. Django-multilingual has admin integration and a multi-language flatpages app. Another nice thing about this app is that it’s using signals internally. The API is based on getter and setter methods. For instance you call get_<fieldname>(language_id=None) on your model to get the field value for the active translation. This app has no releases and less than satisfactory API documentation and has tests only on the example project.
Django-pluggable-model-i18n
Django-pluggable-model-i18n uses registration pattern of admin app. It creates an extra model for translated fields and stores translations of non-default languages in it. This app has no releases, no tests, no API documentation and it is clearly stated to be experimental. I would also like to note the last commit date is May 25, 2009.
Django-modeltranslation
Another app that implements registration pattern is django-modeltranslation. The advantage of registration pattern is you don’t have to modify the code of the 3rd party apps you want to translate dynamically. But the database schema still needs to be modified if you are using django-modeltranslation. Also there is one translations.py for the project. I think one translation definition file per app would be better (just like admin does). Django-modeltranslation has intuitive underscore-language_code API but it is somewhat inconsistent; when you read the unsuffixed field you read the currently active language, when you write you write the default language specified in settings.py. Also the modified model stores some redundant data. For instance if your DEFAULT_LANGUAGE is "ES" both <fieldname> and <fieldname>_es columns will store the same value. Django-modeltranslation has admin integration and a management command to update database schema. Most importantly this app is the only one which has both tests and a release. (Unfortunately tests require specific settings to run)
Transdb
Transdb takes a completely different approach to dynamic translation problem. It provides two new field types; TransCharField and TransTextField. Then it serializes all your translations within a single column for each field of those. This means no ``JOIN``s and no extra queries. Unfortunately transdb doesn’t implement underscore-language_code API, you need to use get_in_language() and set_in_language() methods. Transdb has default widgets that render one form field for each language. Last commit date is Nov 07, 2008 and there is a release.
Django-multilingual-model
This one is not actually an app but just one module with 42 lines of code. You need to define the model that holds translations manually. This introduces some code redundancy, since you also define which fields get translated in the original model. Django-multilingual-model doesn’t implement any translation API, so it’s rather verbose to do anything with it. There are no tests and no releases. I simply don’t recommend django-multilingual-model for anything serious.
Django-transmeta
Django-transmeta stores translations in extra columns it creates in the original field’s table similar to django-modeltranslation. But you enable translation assigning a metaclass for your model and then add a Meta attribute; this means you can’t make models in existing apps translatable without modifying their code. Django-transmeta implements underscore-language_code API, has admin integration and a management command to sync database when you add new languages or translatable fields. There are documentation and code examples but no tests or releases. Last commit date it Nov 24, 2009.
Software development is making choices. Would you rather have a clean and stable schema with an extra translations model or avoid extra JOINs and denormalize translations onto your original model’s table? Both have advantages and disadvantages. But some choices are not based on trade-offs. Documentation, examples, tests and releases for instance. Also in my opinion underscore-language_code API is way better than any of the alternatives.
Django platform is a very powerful and intuitive one. Many people have moved in last year. This popularity affected app ecosystem as well. But unfortunately a significant number of those apps are half baked fire-and-forget type. I wish 2010 to be the year of a significant increase in software quality of Django apps. I’ll try to do my part.
ProFORMA: Probabilistic Feature-based On-line Rapid Model Acquisition
I came across this amazing research project via @dogacan today. The technology described is a combination of video tracking and image-based reconstruction. Watch the video below, it’s awesome!
The final model has some minor artifacts (especially in concave sections) but very nice looking otherwise. I wonder how well it handles complex geometries and deep cavities.
They say, in the project page, there will be a Linux-based demo released in a few months. You can leave your e-mail there if you want to get notified.
Django Fixtures
A fixture is basically a data dump in a specific format. There is no restriction of which models or how much data a fixture can contain. Fixtures are portable. They work the same with all the database backends and operating systems supported by Django. This means that you can use fixtures as a simple data migration tool[1]. Django supports a number of formats by default. JSON format is widely used in the community. But you can easily create serializers for other formats. Although it is not a requirement, all built-in serializers produce human-readable output. Therefore fixtures are an ideal way to keep your data and code together without tightly coupling them.
One limitation you should be aware of is that fixtures are deserialized with the absolute values of primary keys. This makes it difficult to store permissions in fixtures. Also, say, you have two different fixtures for the same model with overlapping pk values. If you load both, instances with overlapping pk’s will be overwritten by the second load.
Test Fixtures
Fixtures are most useful during testing. They are an easy, reliable way to test your app with some data. If you prefer unittests like I do, here’s how to attach fixtures to your TestCase:
from django.test import TestCase
class MyTestCase(TestCase):
fixtures = ['test_users', 'test_foos.json', 'test_bars.xml']
# rest of your class
Here is a tip for preparing fixtures quickly:
- Enable admin for your app. Just registering your models should be enough.
- Create and/or edit test data via admin.
- You can also use Django shell[2] for test data creation.
- Dump your data as intermediary fixtures[3].
- Manually perform any final editing if necessary and save.
This method might look like a lot of work. But it is actually very practical to prepare your test fixtures, or fixtures of any kind this way. Most of the work is removing unneeded data and tweaking the primary keys in the final step. But it is still faster than manually writing the whole thing.
Initial Data
If you want to load some data right after creating your database tables, you provide initial_data fixtures. At the end of syncdb (and flush), Django automatically loads fixtures in your installed apps[4] named initial_data regardless of their format.
This is good if your app require some data to function correctly. But there is a pitfall; as stated in Django documentation your initial_data fixture will be loaded every time you run syncdb. And if you edit these entries they will be overwritten next time you run syncdb. Therefore initial_data is only good for data immutable in nature, such as units of length.
If you want to supply initial data for your project it is better to create one or more bootstrap fixtures and load them manually. Here is my minimal list of things I put in my bootstrap fixture:
- An auth.User as my superuser. It is much easier to load a superuser from fixtures than to create it interactively. I always run syncdb with --noinput and just change my superuser’s password once when I deploy.
- A profile for my superuser.
- A sites.site object.
And of course if all of the following fixtures will be loaded when you issue manage.py loaddata bootstrap command:
- project_dir/myapp1/fixtures/bootstrap.json
- project_dir/myapp1/fixtures/bootstrap.xml
- project_dir/myapp2/fixtures/bootstrap.json
- project_dir/myapp3/fixtures/bootstrap.yml
I think it would be nice if re-usable app authors agreed upon a convention like naming initial data fixtures bootstrap.
[1] | For very little amount of data this works fine. But serialization/deserialization becomes unreasonably slow for larger data sets. Then it’s better to use native tools for your database, modifying the input if necessarily. |
[2] | Use manage.py shell command to enter Django shell. |
[3] | Use manage.py dumpdata <app_name> > <out_file> command to dump your app data as a fixture. By default Django uses JSON format. If you add --indent=2 it will make the output much easier to read and edit. |
[4] | Apps that are in your settings.INSTALLED_APPS. |
Django: Testing With File System Side Effects
Django uses unittest for testing. django.test.TestCase is a special base class for tests that adds various features[1]. Django testing framework takes care of creating a test database, resetting it to its initial state after each test and finally destroying it. So you don’t have to worry tests overwriting anything in your main database.
But if your tests need to create, modify or delete files you need to make sure these side effects are contained. For instance if one of your applications is generating or uploading files within your MEDIA_PATH you would rather not let it mess with files already there.
Here is a little example of using a temporary folder for such operations:
import shutil
import tempfile
from django.test import TestCase
class FooTestCase(TestCase):
def setUp(self):
self.__old_foo_dir = settings.FOO_DIR
settings.FOO_DIR = tempfile.mkdtemp(suffix='foo')
def test_foo(self):
# some tests with filesystem side effects
pass
def tearDown(self):
shutil.rmtree(settings.FOO_DIR)
settings.FOO_DIR = self.__old_foo_dir
Here tempfile.mkdtemp() creates a temporary directory for us and returns its path. When we are finished we remove this temporary directory with shutil.rmtree() and restore our setting FOO_DIR back to its original value. It is always best to clean up thoroughly. We don’t want our tests to fail because of themselves.
Assume settings.FOO_DIR was a directory under MEDIA_PATH. So when you diverted FOO_DIR to the temporary directory, files within couldn’t be served with media server or your development server (if you have configured it to serve static files). If for some reason you need these files accessible over HTTP you need to re-configure your media server. In case of development server it is relatively easy; just divert whole MEDIA_PATH and copy needed files to temporary directory. I suppose you can get away without copying static files to the new location in case of a real media server, nevertheless configuration will be somewhat difficult and a restart might be necessary.
[1] | For more information you can refer to official documentation. |
Bodybuilding Supplements For Beginners
I see people asking gym instructors for supplementation advice. And those schmucks are invariably telling they should buy amino acids. This is wrong. Just as any other advice from those ignorant fools it should be best avoided. But maybe it is as foolish of them as usual; you see aminos cost approximately three times what protein powders cost.
Do beginners need amino acid supplementation? Hell, no! No, no, NO! You don’t even need protein powders. Don’t rely on supplementation. There are no magic pills. Well, there are magic pills with magical effects. But they can also kill you or cause serious chronic diseases. Reasonably safe supplements on the other hand, regardless of what advertisements say, have way lower potency. So don’t rely on supplements, you would only be deceiving yourself and wasting money.
I frequently hear oversimplified explanations and defintions such as L-Cartinine is a fat burner or proteins build muscle. Human body is a complex machine. It is just naive to believe you can simply stick something in your body and expect (positive) results. For instance L-Carnitine helps burning fat, but if you don’t combine it with physical activity you will have no results. No matter how much L-Carnitine you take, you won’t lose fat just by taking it. Same goes for protein supplementation. The more the better approach will only make you fat.
Master The Real Food First
How should beginners supplement then? First of all, know what you are doing. Since you are reading this now, you have Internet access. Just try to educate yourself as much as you can. This is your health, it should worth the time. Second of all, keep it simple in the beginning. Here is my short list of supplements:
- Real food. Rice, chicken, eggs, fruits, vegetables… You need to make sure you are getting enough of these. Enough and not too much. Not too much but diverse enough. If you are not eating right, supplements will have even less positive effects.
- Vitamins and minerals. I know you want to start munching those animal-giga-nitro-x’s right now. But your body won’t really respond hype. Make sure you take enough micronutrients. Remember extra stress caused by workout increases your need. Consult your doctor for precise amounts. Especially important for bodybuilders are:
- Vitamin C
- Vitamin B
- Zinc
- Magnesium
- Potassium
- [optional] Post workout shake. This is not a necessity, but if you happen to have a fast metabolizing protein (such as powdered whey protein) take it just after your workout. This is one of the best times to take supplements.
Take-away here, is that you don’t need fancy supplements when you are just beginning. They won’t do wonders as they are advertised. They won’t even make a significant difference to be honest. Concentrate on other aspects of bodybuilding. Learn how to train right. Make sure you rest enough. Eat real, healthy food.
And of course; have fun!