Vitaliy Khe
Vitaliy Khe

Reputation: 23

How reuse __str__ function in models.py for each class model

Hello everyone I start use Django Framework and I have a question.

Django's documentation says, when I create class(model) in the end of class I should write function to return string value for my object, it all look like this:

class NameClass(models.Model):
    field_name_1 = models.SomeTypeField()
    field_name_2 = models.SomeTypeField()
    field_name_3 = models.SomeTypeField()
    ...
    field_name_n =  models.SomeTypeField() 
    def __str__(self):
        return self.field_name_1, ...self.field_name_n 

In this case I wrote function for return string value, cause I have a lot of fields in my models and write each of them in __str__ function it will be a lot of work. So my function look like this:

def __str__(self):
    fields =''
    for x in self._meta.fields:
        fields = fields + string.split(str(x),".")[2]+' '
    return fields

Now question. How can I reuse this function in each class(model) in model.py, without copy paste this function?

For example. I have a lot of classes(mdoels):

class FirstModel(models.Model):
    ...
    def __str__(self):
        ...
class SecondModel(models.Model):
    ...
    def __str__(self):
        ...

class ThirdModel(models.Model):
    ...
    def __str__(self):
        ... 
class EtcModel(models.Model):
    ....
    def __str__(self):

And I don't want copy paste my function everytime, may exist some way to use it like a global function or another way to solve it.

Upvotes: 1

Views: 1306

Answers (4)

mirek
mirek

Reputation: 1350

Inheritance:

class MyBaseModel(models.Model):
    ...
    def __str__(self):
        ...
class FirstModel(MyBaseModel):
    ...
class SecondModel(MyBaseModel):
    ...
    def __str__(self):  # you can adjust the inherited method 
        retval = super().__str__()
        return retval + ' ' + self.fld10

Upvotes: 0

allcaps
allcaps

Reputation: 11248

If your classes only share the same methods you can use a mixin:

class BaseMixin(object):
    def __str__(self):
        return self.something

class Foo(BaseMixin, models.Model):
    # ...

For all models that share the same fields and methods, you can create a abstract base class Eg:

class Base(models.Model):
  class Meta:
      abstract = True
  title = models.CharField(max_length=255)

  def __str__(self):
      return self.title


class Foo(Base):
    # ...

Upvotes: 0

frederick99
frederick99

Reputation: 1053

Outside, define a function,

def foo(obj):
    fields =''
    for x in obj._meta.fields:
        fields = fields + string.split(str(x),".")[2]+' '
    return fields

Inside the class,

class FirstModel(models.Model):
    ...
    __str__ = foo

Upvotes: 0

khelwood
khelwood

Reputation: 59155

You could use inheritance (inherit your different classes from one base class that provides the __str__ method you want).

Or if that doesn't work for you, and you just want to share this method implementation in the easiest way possible, you can assign methods in your classes instead of defining them.

def mystrfunction(self):
   return whatever

class Class1(object):
   ...
   __str__ = mystrfunction

class Class2(object):
   ...
   __str__ = mystrfunction

Upvotes: 1

Related Questions