Reputation: 377
I have model with field named "number". It's not the same as id, it's position while displayed on website, users can sort teams around.
I need something for default property of number. I think I should just count the number of positions in the database and add one, so if there are 15 positions inside db, the new team would be last on list and have "number" 16.
But I don't know how to do it, inside models.py file.
Inside views.py I would just use
Iteam.objects.count()
But what can I use inside model declaration? How can the model check itself?
Edit:
I tried do it as Joey Wilhelm suggested:
from django.db import models
class ItemManager(models.Manager):
def next_number(self):
return self.count() + 1
class Iteam(models.Model):
name = models.CharField()
objects = ItemManager()
number = models.IntegerField(default=objects.next_number())
Unfortunetly i get error:
AttributeError: 'NoneType' object has no attribute '_meta'
Upvotes: 0
Views: 275
Reputation: 5819
This is actually something you would want to do on a manager, rather than the model itself. The model should represent, and perform actions for, an individual instance. Whereas the manager represents, and performs actions for a collection of instances. So in this case you might want something like:
from django.db import models
class ItemManager(models.Manager):
def next_number(self):
return self.count() + 1
class Item(models.Model):
number = models.IntegerField()
objects = ItemManager()
That being said, I could see this leading to a lot of data integrity issues. Imagine the scenario:
Edit:
The above approach will work only for pre-generating 'number', such as:
Iteam.objects.create(number=Iteam.objects.get_number(), name='foo')
In order to have it work as an actual default value for the field, you would need to use a less savory approach, such as:
from django.db import models
class Iteam(models.Model):
name = models.CharField()
number = models.IntegerField(default=lambda: Iteam.get_next_number())
@classmethod
def get_next_number(cls):
return cls.objects.count() + 1
I would still warn against this approach, however, as it still could lead to the data integrity issues mentioned above.
Upvotes: 1