Reputation: 942
OK here goes, this is one of those questions that makes perfect sense in my head but is difficult to explain properly :) I have a django app where I want to store records for lots of different items of equipment. Each type of equipment will have a custom model to store its attributes, such as MyEquipment
below. Each type of equipment will also have a 'category', which would be useful to store as an attribute.
class Category(models.Model):
code = models.CharField('Category', max_length=4, unique=True)
description = models.CharField('Description', max_length=30)
...
class MyEquipment(models.Model):
serial = models.IntegerField()
...
To save this attribute to my model I could use a foreign key to Category
but I don't need to because every record in MyEquipment
must be the same Category
. So then I thought maybe I could hardcode the Category
in the MyEquipment
meta like this:
class MyEquipment(models.Model):
serial = models.IntegerField()
...
class Meta:
category = Category.objects.get(code='EC')
But then this would rely on the Category
model being populated with data to build the MyEquipment
model. To me this doesn't seem best practice, using data that may or may not exist to define the structure of another model. Is there a better way I should be using to set which Category
the MyEquipment
model is related to?
EDIT
Thanks for the discussion below, it's made me realise perhaps I wasn't clear on my original post. So what I want to do is have a way of linking MyEquipment
to a Category
. So I can do something like this:
>>> from myapp.models import MyEquipment
>>> MyEquipment.CATEGORY
<Category: EC>
I want to link the whole model to a Category
, so I can process each model in different ways in my view depending on which category it is. Having thought about the problem a bit more, I can get this functionality by writing MyEquipment
like this:
class MyEquipment(models.Model):
CATEGORY = Category.objects.get(code='EC')
serial = models.IntegerField()
...
This way works, but is it the best way? I guess the model would do this get operation everytime the class is instantiated? Is there a more efficient method?
Upvotes: 0
Views: 952
Reputation: 504
but ... every record in MyEquipment must be the same Category
Then you don't need any relationship. As you said already, every record in MyEquipment are same Category, why do you want to store relation in db?
UPD: Solution with model inheritance
class Place(models.Model):
category = models.ForeignKey(Category)
class Meta:
abstract = True
def save(self, *args, **kwargs):
self.category = Category.objects.get(name=self.CATEGORY)
return super(Place, self).save(*args, **kwargs)
class Restaurant(Place):
...fields...
CATEGORY = 'RE'
class Building(Place):
...fields...
CATEGORY = 'BU'
Upvotes: 0
Reputation: 599788
You can't do this anyway; the Meta class doesn't support arbitrary attributes.
The best thing would be to define this as a property, which you can access via the instance itself. To make it more efficient, you could memoize it on the class.
@property
def category(self):
_category = getattr(self, '_category', None)
if not _category:
self.__class__._category = _category = Category.objects.get(code='EC')
return _category
Upvotes: 2