Django model class and custom property

2020-04-11 08:24发布

问题:

Howdy - today a weird problem occured to me:

I have a modle class in Django and added a custom property to it that shall not be saved into the database and therefore is not represent in the models structure:

class Category(models.Model):
    groups = models.ManyToManyField(Group)
    title = defaultdict()

Now, when I'm within the shell or writing a test and I do the following:

c1 = Category.objects.create()
c1.title['de'] = 'german title'
print c1.title['de'] # prints "german title"

c2 = Category.objects.create()  
print c2.title['de'] # prints "german title" <-- WTF?

It seems that 'title' is kind of global. If I change title to a simple string it works as expected, so it has to do something with the dict? I also tried setting title as a property:

title = property(_title)

But that did not work, too. So, how can I solve this? Thank you in advance!

EDIT:

Here is the intention of the base problem to provide you a better look to the whole surrounding enviroment as requested: In our model structure we have a model class that stores translations. This class is unbound from all the other classes that have relations between each other. The translation class stores the translated value, a language key, a translation key and the package and class the translation belongs to. Some model classes can have properties that can be translated into different languages. These properties are not mapped within the django model structure as this is not truely possbile in our eyes. Each of this classes with translatable properties, let's call them translatables, can have one or more of these properties. That's the translation key is for. E.g. if there is a class Category with a translatable property "title", the model translation will store "module.somewhere.Category" as package/class, "title" as translation key, and e.g. for german the translation value "Kategorie" and the language key "de". My aim is to ease the access to this properties. So all this model classes inherit from a plain class called "Translatable". It has a method for resolving the module path and name of the class (for the later storing within the translation database table) and a "_propertize" method that takes the name of the property. Propertize instantiates a class "Translator" that is unique for each translatable property name. This class does the resolving of the real translation value from the translation model class and some stuff for automatically resolving the translation of currently chosen language.

回答1:

Don't do it that way. Your title attribute is completely "global". It's part of the class, not part of each instance.

Do something like this.

class Category(models.Model):
    groups = models.ManyToManyField(Group)
    @property
    def title(self):
        return self._title
    def save( self, *args, **kw  ):
        try:
            self._title
        except AttributeError:
            self._title= defaultdict()
        super( Category, self ).save( *args, **kw )

If you could define your actual use case, it might be possible to simplify this a great deal.