views:

43

answers:

3

Hi Guys, Django newbie here,

I have several types of models, in each of them the fields have different names (e.g. first_name, forename, prenom) and I want each of the models to contain a mapping so that I can easily approach each of the fields using one conventional name (e.g. first_name for all of the field names). what's a good way of doing this?

A: 

You could make your models all inherit a new model that has a property function defined to get/set the right variable.

class BaseNameClass(models.Model)

    def getfname(self):
        if hasattr(self, 'first_name'): return self.first_name
        if hasattr(self, 'prenom'): return self.prenom
        if hasattr(self, 'forename'): return self.forename

    def setfname(self, x):
        if hasattr(self, 'first_name'): self.first_name = x
        if hasattr(self, 'prenom'): self.prenom = x
        if hasattr(self, 'forename'): self.forename = x

    firstname = property(getfname, setfname)

And then change your models to all inherit from that. It will be slightly slower but we're talking nano and milliseconds.

If you had an descendant object called person, you'd access the name simply by:

print person.firstname
person.firstname = "oli"
print person.firstname
Oli
Hi Thanks for the answer, but I was looking for something that will reside in the specific models themselves, not the main model... meaning that each model will know how to translate first name..
apple_pie
You could dump this code in each model if you wanted to (of course without the class definition line)... I just thought if you inherited it from a central class, you'd save on code replication.
Oli
Yes, but conceptually each model should know its unique field name, and thus you can add and remove models without changing the base model.
apple_pie
+2  A: 

You could define a @property on each of your models, like this:

class Personage(models.Model):
    prenom = models.CharField(max_length=255)

    @property
    def first_name(self):
        return self.prenom

then you can just reference your new property like this:

personage = Personage.objects.all()[0]
personage.first_name
jturnbull
thanks, is there a similar thing in forms?
apple_pie
+3  A: 

I think the best way would be to use conventional names in your models and provide only one obvious way to access it. If you don't wan't to change the database columns too, you can use the db_column option. Example:

class Person(models.Model):
    first_name = models.CharField(max_length=255, db_column='prenom')

class Customer(models.Model):
    first_name = models.CharField(max_length=255, db_column='forename')

class Worker(models.Model):
    first_name = models.CharField(max_length=255) # column is also called "first_name"

If you need to provide different ways to access the members (which I would try to avoid!) you can still add properties to each model.

tux21b
good answer, but I still need different ways to access the members.
apple_pie