Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set default value of a field using classmethod in Django

I've found many similar posts on the web about this topic but no one state clearly which is the problem.

Code

class Item(models.Model):
    @classmethod
    def get_next_item_number(cls):
        return cls.objects.count() + 1

    number = models.IntegerField(default=get_next_item_number)

Problem

When I access Django admin panel the text field related to 'number' field contains

<classmethod object at 0x7fab049d7c50>

So I tried to change the code above

class Item(models.Model):
    @classmethod
    def get_next_item_number(cls):
        return cls.objects.count() + 1

    number = models.IntegerField(default=get_next_item_number())

but when I run django server I get:

number = models.IntegerField(default=get_next_item_number())
TypeError: 'classmethod' object is not callable

I know all this could be prevented by declaring get_next_item_number() as an external function but this solution is not elegant to me because get_next_item_number() refer only to Item class.

Is there a solution I'm missing?

like image 279
Sirion Avatar asked Sep 02 '14 11:09

Sirion


People also ask

What is __ str __ in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model.

What is AutoField in Django?

According to documentation, An AutoField is an IntegerField that automatically increments according to available IDs. One usually won't need to use this directly because a primary key field will automatically be added to your model if you don't specify otherwise.

How do I override a save in Django?

save() method from its parent class is to be overridden so we use super keyword. slugify is a function that converts any string into a slug. so we are converting the title to form a slug basically.

How Django knows to update VS insert?

The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.


1 Answers

I found this solution:

Code

class Item(models.Model):
    @staticmethod
    def get_next_item_number():
        return Item.objects.count() + 1

    number = models.IntegerField(default=get_next_item_number.__func__)

I'm not completely aware of the possible consequences, but it works.

like image 191
Sirion Avatar answered Oct 18 '22 01:10

Sirion