I’m creating custom class based views for a Django project and faced a design decision concerning attributes.
Getter functions
I looked at Django’s generic views, and saw that there are quite a lot of classes that provide both class variables as well as custom getter functions. e.g.
class FormMixin(object):
initial = {}
def get_initial(self):
return self.initial
This design decision makes sense, because that way, you can call super() in an overriding method of an extending class.
Properties
In my project, there are certain values that I could sometimes override using a simple value, but that sometimes have to be generated dnyamically. At first I created methods similar to the above, but then thought that maybe properties are a nicer way to do this.
class MyBaseView(OtherView):
counter = None
class MyExtendingView(MyBaseView):
counter = 5
class MyOtherExtendingView(MyBaseView):
@property
def counter(self):
return self.other_function()
instance.__dict__
I plan on using those values inside a template. I pass instances of the extending views to a template and display the attributes in the following way:
context['class_instances'] = [MyExtendingView(), MyOtherExtendingView()]
{% for instance in class_instances %}
{{ instance.counter|default:'' }}
{% endfor %}
Now as this is a template, and it doesn’t really matter whether the instance attribute is a value or a function, I could also write my classes like this:
class MyExtendingView(MyBaseView):
counter = 5
class MyOtherExtendingView(MyBaseView):
def counter(self):
return self.other_function()
The def counter will replace the old value-based attribute in instance.__dict__.
Question
To get to the question, which of the listed approaches is the best choice?
- The getter approach is nice, as it allows
super()-calling the parent’s getter function, but in most of my cases that will probably never be needed. - The property approach is much simpler and causes less code to be written. I can’t
super()-call a parent’s property function though. I won’t be needing this behavior in most cases, but there could be cases where I needsuper()functionality, so there would be a mix of simple attributes that can be overridden using properties and custom getter functions. - The last approach is even less code than the property approach, but I doubt it’s good style.
You actually can access parent properties via
super():