tama
tama

Reputation: 315

Making a function available to all models

I have the following function in one of my models

def get_fields(self):
   return[(field.name, field.value_to_string(self)) for field in MusicPack._meta.fields]

Which helps me iterate over all the fields of a model and display them into a template. How would I implement this to all my models without replicating the two lines in every model in my database?

Would I just make a superclass that contain the function for all models and then have all my models children of it?

template.html

<div id = "subtemplate">
    <ul>
    {% for model in object_list %}
        <div class = modeldiv>
        {% for name,value in model.get_fields %}
            <li>
            {% if value %}
            {{ name|capfirst }} : {{ value }}
            {% endif %}
            </li>
            {% endfor %}
            </div>
            {% empty %}
            <li> No objects created yet. </li>
            {% endfor %}
   </ul>
</div>

Upvotes: 1

Views: 64

Answers (2)

gilsho
gilsho

Reputation: 921

Putting that method in a base class is certainly one way to do it. Another approach is to have it be a generic utility function in some utility module that prints all fields in an object, which you can call before rendering your template.

from myproject.utilities import get_fields

...

return render_template("template.html", get_fields(model))

Yet a third approach is to write a class decorator which provides this functionality to a class:

class with_get_fields(cls):

    def __init__(self, *args, **kwargs):
        cls.__init__(self, *args, **kwargs) 

    def get_fields():
         return [(field.name, field.value_to_string(self)) for field in cls.fields]

and then apply it to any model class that you wish to have this functionality

@with_get_fields
class model():

       def __init___(self):
           ...

Upvotes: 0

Rod Xavier
Rod Xavier

Reputation: 4043

You could use Mixins.

Example

class Mixin(object):
    def get_fields(self):
        return[(field.name, field.value_to_string(self)) for field in self.__class__._meta.fields]

class A(models.Model, Mixin):
    ...

class B(models.Model, Mixin):
    ...

Upvotes: 1

Related Questions