Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model class methods for predefined values

I'm working on some Django-code that has a model like this:

class Status(models.Model):     code = models.IntegerField()     text = models.CharField(maxlength=255) 

There are about 10 pre-defined code/text-pairs that are stored in the database. Scattered around the codebase I see code like this:

status = Status.objects.get(code=0) # successful status = Status.objects.get(code=1) # failed 

I would rather have a method for each so that the code would look something like this instead:

status = Status.successful() status = Status.failed() etc... 

Is this possible? I have looked in to the Manager-stuff but I haven't really found a way. Is it time to really RTFM?

In Java it would be a static method and in Ruby you would just define a method on self, but it's not that easy in Python, is it?

like image 498
Jörgen Lundberg Avatar asked Feb 06 '10 13:02

Jörgen Lundberg


People also ask

What is the purpose of __ Str__ method in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model. # Create your models here. This will display the objects as something always in the admin interface.

How does Django model define default data?

You need to create an empty migration file and Do your stuff in operations block, as explained in docs. As well as changing the database schema, you can also use migrations to change the data in the database itself, in conjunction with the schema if you want.

Can Django model have two primary keys?

Do Django models support multiple-column primary keys? ¶ No. Only single-column primary keys are supported.

How can create primary key in Django model?

By default, Django adds an id field to each model, which is used as the primary key for that model. You can create your own primary key field by adding the keyword arg primary_key=True to a field. If you add your own primary key field, the automatic one will not be added.


1 Answers

You should perhaps implement this by defining a custom manager for your class, and adding two manager methods on that manager (which I believe is the preferred way for adding table-level functionality for any model). However, another way of doing it is by throwing in two class methods on your class that query and return resulting objects, such as:

class Status(models.Model):     code = models.IntegerField()     text = models.CharField(maxlength=255)      @classmethod     def successful(cls):         return cls.objects.get(code=0)      @classmethod     def failed(cls):         return cls.objects.get(code=1) 

Do note please that get() is likely to throw different exceptions, such as Status.DoesNotExist and MultipleObjectsReturned.

And for an example implementation of how to do the same thing using Django managers, you could do something like this:

class StatusManager(models.Manager):     def successful(self):         return self.get(code=1)      def failed(self):         return self.get(code=0)  class Status(models.Model):     code = models.IntegerField()     text = models.CharField(maxlength=255)      objects = StatusManager() 

Where, you could do Status.objects.successful() and Status.objects.failed() to get what you desire.

like image 86
ayaz Avatar answered Sep 22 '22 15:09

ayaz