views:

95

answers:

4

I'm working on my first real Django project after years of PHP programming, and I am running into a problem with my models. First, I noticed that I was copying and pasting code between the models, and being a diligent OO programmer I decided to make a parent class that the other models could inherit from:

class Common(model.Model):
    name = models.CharField(max_length=255)
    date_created  = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.name

    class Meta:
        abstract=True

So far so good. Now all my other models extend "Common" and have names and dates like I want. However, I have a class for "Categories" were the name has to be unique. I assume there should be a relatively simple way for me to access the name attribute from Common and make it unique. However, the different methods I have tried to use have all failed. For example:

class Category(Common):
    def __init__(self, *args, **kwargs):
        self.name.unique=True

Causes the Django admin page to spit up the error "Caught an exception while rendering: 'Category' object has no attribute 'name'

Can someone point me in the right direction?

+1  A: 

You have a small mistake in your Common class

class Common(model.Model):
    self.name = models.CharField(max_length=255) 

should be

class Common(model.Model):
    name = models.CharField(max_length=255)
Mark Lavin
think that must be a copy-and-paste issue, since it's not valid Python - self isn't defined at that point.
Daniel Roseman
Sorry about the confusion over the typo. Since I am new to Python I've been experimenting with lots of odd code just to see what happens, and that was one of my experiments which I meant to clean up before pasting into Stackoverflow.Unfortunately, my code doesn't work even with the typo removed
Joshmaker
+2  A: 

No, Django doesn't allow that.

See the docs: http://docs.djangoproject.com/en/1.1/topics/db/models/#field-name-hiding-is-not-permitted

Also answered in other questions like: http://stackoverflow.com/questions/2344751/in-django-model-inheritance-does-it-allow-you-to-override-a-parent-models-at

gomad
I'm a little shocked to see that in the docs... that seems like a pretty big omission!
Joshmaker
Well, model inheritance was missing entirely from Django for quite some time, so I think this is a big improvement. I'm not entirely sure, but I think you might be able to implement your unique=true in a custom manager. Or, you might be able to use multiple inheritance and have the UNIQUE_NAME as a mixin.
gomad
A: 

Try using Meta.unique_together to force it into its own unique index. Failing that, it's probably easiest to create two separate abstract classes, one with the field unique and one not.

Ignacio Vazquez-Abrams
+1  A: 

Note that UNIQUE constraint in fact has nothing to do with Django, so you're free to add it in your database table. You can also use post-syncdb hook for that purpose.

Tomasz Zielinski