Sunday, January 6, 2008

getting to pesky foreign key data in django

Optimizing databases is a good practice and should be done for any enterprise applications, but as all things go there is a price to pay. The price you pay is when calling back and displaying the data into one can be real PITA. django is a damn good framework and allows you to do work fast with a pedal-to-the-metal feel but then certain amounts of work still has to be done when you have foreign keys defined.

Say you have a database with two tables : contacts and address. The relationship of the two tables are of the one to many kind, I could never really wrap my head around the one-many many-one many-many thingy so let me just say it in layman so I understand it better myself. "One contact can have one or more than one address"

class Contacts(models.Model):
..... bla bla

class Address(models.Model):

customer_id=models.ForeignKey(Contacts,edit_inline=models.STACKED,num_in_admin=2)


So in the code above you have basically linked both the tables together using a ForeignKey relationship. the 'edit_inline' ... mumbo jumbo just tells django to add the address field into the main Contacts form during creation and modification and not as a pop up link ( This is important and could be a clincher for normal users ).

Calling all the data back for display

Okay so now you are honky dory with a great admin form for you to add data into your database, now the problem starts when you want to call all the data back for display in your template.

Don't worry django comes with little helper functions, you just have to do a few more steps to display your foreignkey data.

For my case, in my view.py I do something like this :


from stock.models import Contacts

def main(request,id):
contact_list = Contacts.objects.get(id=id)
return render_to_response('stock/mytemplate.html',{'contacts':contact_list})

Probably the html formatting would made my code not valid in python, but just check ur identation especially after the function definition.

The few lines of code above basically expects you to send it an id ( from the url using the GET method ) and then get the Contacts object and then packs up that data object and sends you merrily along to your template with that.

Okay, a bit about the Contact objects. Inside your contact objects if you have a foreign key relationship it automatically create a method for you to access the data. The method is called _set. So following our example, we know that we have a relationship with the table Address, so we can expect that each contact object will have a method called 'address_set'. Still okay so far ? Lets go ....to get the data you normally call it like this :

contact_list.address_set.select_related()

This returns an orm object inside a list, so on your template you will call it like this :

{% for address in contact.address_set.select_related %}


Address: {{address.address|escape}}




{% endfor %}



That will bring up and display all your address for that particular contact. Done ! Easy peasy, well for me at least just comment me if think more clarification...
Post a Comment