views:

592

answers:

4

I have a couple of tables that are joined by GUIDs in SQL Server. Now, I've found a few custom fields to add support for GUIDs in django, but I tend to shy away from using code in blog posts if at all possible. I'm not going to do anything with the GUID other than join on it and maybe assign a GUID on new entries (although this is optional). Is there any way to allow this using django's built-in types? Like can I use some kind of char field or binary field and "trick" django into joining using it?

If it's any help, I'm using django-pyodbc.

A: 

If I do a python manage.py inspectdb the output is something like this:

class SomeModel(models.Model):
    uid = models.TextField(primary_key=True)

class SomeOtherModel(models.Model):
    uid = models.TextField()

This doesn't work though. For whatever reason, this won't work if uid is the primary key. So I change it to this:

class SomeModel(models.Model):
    uid = models.TextField()

class SomeOtherModel(models.Model):
    somemodel = models.ForeignKey(SomeModel, db_column='uid', to_field='uid')

This seems to work, but is painfully slow.

Jason Baker
Why not change it to CharField(primary_key=True)?
webjunkie
Ah, that works. Thanks.
Jason Baker
A: 

For those who actually need to generate GUIDs:

guid = hashlib.sha1(str(random.random())).hexdigest()
Adam Nelson
+3  A: 

I'd create a basic GUID Model in order to reuse it's properties for any other models in my projects. Model inheritance is working nicely since several versions prior to Django 1.0 and is quite stable with Django 1.0.

Create something like project/common/models.py and place there this class:

import hashlib
import random
from django.db import models

class GUIDModel(models.Model):

    guid = models.CharField(primary_key=True, max_length=40)

    def save(self, *args, **kwargs):

      if not self.guid:
        self.guid = hashlib.sha1(str(random.random())).hexdigest()

      super(GUIDModel, self).save(*args, **kwargs)

Then create your other models as usual:

from common.models import GUIDModel

class Customer(GUIDModel):
  name = models.CharField(max_length=64)

class Product(GUIDModel):
  name = models.CharField(max_length=64)

class Sale(GUIDModel):
  customer = models.ForeignKey(Customer)
  product = models.ForeignKey(Product)
  items = models.PositiveIntegerField()

And everything should work nicely with GUIDs as primary keys instead of autoincremental integers.

gnrfan
I might suggest using the python uuid module and generating new guids either with uuid.uuid1() or uuid.uuid4().
Craig Trader
To make this code work with forms, you need to add blank=True to the GUIDModel. This allows the form to validate; we never actually end up with a blank guid because save() ensures that there is a value.
Rich
+1  A: 

Take a look at Django-extensions UUID Field

Jj