Reputation: 315
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
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
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