Aug 24, 2011

Django: Virtualenv with Eclipse befrending

Hi!
Many people use Virtualenv. It has become common pattern now days. I like Virtualenv but it has no debugger. You can run 'python manage.py runserver' but it will newer help you see somthing like runtime variables and code flow. I like PyDev debugger. It helps me a lot.
Anyway I faced a problem recently. My employer wants me to run code at virtualenv. I needed to download and run project. I made it creating New virtualenv called 'venv' inside a project folder. Command is:

virtualenv --no-site-packages venv


It will create dir 'venv' inside current directory. So you should be at where you need to store your virtualenv (your project directory for e.g.). --no-site-packeges parameter says that your new virtual environment will not have packages installed in system. It's a must if you want to avoid collisions with newer versions of code.

Now we have a dir inside your project called venv containing our separated python environment. Lets activate it using command:

$ source venv/bin/activate


Your terminal will gain '(venv)' prefix at the beginning, indicating that we are now using alternative PYTHONPATH configuration. Now you may work almost like using normal system shell, except your PYTHONPATH is set tot  this newly created folder venv and all changes are stored inside it ONLY!

Lets make our dirty work. Usually it's something like in my case:

pip install -r requirements.txt


Or you can simply:

$ easy_install django


For the sake of test :). Anyway it's not the main point of an article.

I assume You already have eclipse project set up properly. I have an article about it: Installing Eclipse and PyDev for django. It also has some unralated info at first, about installing Eclipse from scrtch, but you can start reading from about in the middle of the text. It says how to set up a new project.

Anyway main point of befriending PyDev, Eclipse and virtualenv is IMHO the best way to do so:

1. Point your project's (in Eclipse) PYTHONPATH variable to your virtualenv dir's site-packeges.
To do so go to your project Properties, selecting it from the right mouse button context menu or any other way and select Python - PYTHONPATH option there. It might be like So:




2. Now add a directory inside your newly created virtualenv directory. (venv in my case) You mus not add the whole directory venv but a site-packages dir inside of it. It usually lies at this path:

$ venv/lib/python$$$/site-packages 
#where $$$ is your python version used for virtualenv created (2.7 in my case)


It may look like this:


3. Ta-da thats ALL!. Now hit Ok/Apply to save your settings and try to run/debug your project from eclipse using run/debug buttons. It Should be working right now. You need to create a proper run configuration BTW. But it's another whole story.


Comments and suggestions are welcome. Please write if you found it useful or not :)

Aug 12, 2011

Django: How and why to use migrations. Django-South.

Hi there guys and we're here to talk about migrations today. My app grown to complex app with profiles, social registration permits and so on. First time I've decided to make myself a simple app. Now it became complex enough and contains enough code to need code comments :). Anyway Migrations is a process anybody someday will need. I thought it's hard to learn or understand, but it's not.

Main point is that you:
- save your current database tables structure
- change your model tables
- scan for differences and create script
- then write changes to your database with automatically generated python script.

Sound's simple? I't not all so simple in fact. App that you need to learn is Django-south. Its main objectives are to provide a simple, stable and database-independent migration layer to prevent all the hassle schema changes over time bring to your Django applications. It has quite understandable tutorial here.

So if you're tired of ALTER'ing your tables and writing code to python Sqlite console or editing raw SQL, go get yourself a copy of south. It's an app that IMHO everybody should use/hear/understand.

It is meant to change old one and quite simple command 'manage.py syncdb' someday. For now go get yourself this tool and learn to use it. It took me about half an hour to understand basics.. So it's not hard (at first) :).

Brief look at usage:

1. Install app in some way. Use pip/easy_install script or simply put 'south' dir to your project root dir.
Add 'south', to your INSTALLED_APPS dictionary.
!IMPORTANT! you need to make syncdb after that. Another way wo will get an error with future commands.

2. Connect existing app's to migrations. Use command python manage.py convert_to_south myapp to convert your app from syncdb ready to south migratable. Or you can run python manage.py schemamigration newappname --initial to add south migrations ability to your new app. In general it will create directory 'migrations' inside your app directory.

3. Change your model. I dont think you need separate stop here. But... Just in case add some field to your django model like bollean or text and/or edit your existing field rather by adding 'null=True' for e.g.

4. Create your migration. It can be done by command python manage.py schemamigration newappname --auto to create your migration script. you can check it in your app's 'migrations' dir. It has numbers in the beginning with migration number.

5. Run your migration. It is done by command python manage.py migrate appname or even without an app name: python manage.py migrate to migrate all apps. Thats it.

Hope you'll never use 'syncdb' again for complex tasks like this. I'm adding it to my base developer tools. And you?

Aug 1, 2011

Django: adding code execution on your app syncdb, or how to use Django Signals.

Hi there and let's talk about app initialization in Django. There are some cases when you want to initialize a Django app with creating some default values in database. In my case it was necessity to create default album in database to post user photos to. Sometimes you could just use get_or_create for those purposes. But it will be a good example if we will need something more complex in our app initialization; for e.g. generating thumbnails for photos or cleaning unused temporary files etc. So let's get started:

Good place to put your initialization scripts is your app's __init__.py file. You can examine Djangoproject wiki for more info. Anyway here is my code for making this:

  1. from django.db.models.signals import post_syncdb
  2. import models
  3. from models import Album
  4.  
  5. def create_first_album(sender, **kwargs):
  6.     """
  7.    Create your album sequence to create default album to post photos to
  8.    checks for existence of this album and creates one if none exists.
  9.    """
  10.     obj, created = Album.objects.get_or_create(title="User's Posted"
                                                   public=True)
  11.     if created:
  12.         print("Created album 'User's Posted'.")
  13.     else:
  14.         print("NOT CRATED album 'User's Posted'.")
  15.     pass
  16.  
  17. post_syncdb.connect(create_first_album, sender=models)

It is made using Django Signals documentation example. This code creates album 'Users Photos' upon first running os 'syncdb' bu my apps user. It's quite simple but shows the idea.

Main idea here that you need to add code to __init__.py file of your app. It will stick to signal you've chosen (post_syncdb in our case) and execute on it's call. 
Than you will write your function to execute (def create_first_album in our case) and say when to execute this function. We sticked it to post_syncdb signal.

This way cou can handle more handy signals like using pre_init signal to execute some code not only at syncdb but at every app's startup or even add some code to template upon rendering. Read Django docs Signals to know more.