概要
- Djangoのテンプレートで、あらかじめ指定したフィールドだけ表示したい
- Userモデルで、is_activeなど不要なフィールドは見せたくない
-
django.views.generic.DetailView
で表示する想定
- フィールドを後から増減させたときに、なるべく一箇所だけの変更で済ませたい
対応
- modelクラスに、指定したフィールドだけを抽出する関数を追加する
- viewごとに表示するフィールドを変えたい場合は、下記の
viewable_field_list
を上書きする
ソースコード
models.py
class CustomUser(AbstractUser):
# get viewable fields with order.
viewable_field_list = ('userType', 'username', 'email', 'companyName', 'nearestStation')
editable_field_list = ('username', 'companyName', 'nearestStation')
def get_selected_fields(self):
"""Returns a list of selected field names on the instance."""
fields = []
for vf in self.viewable_field_list:
for f in self._meta.fields:
fname = f.name
if vf != fname:
continue
# resolve picklists/choices, with get_xyz_display() function
get_choice = 'get_'+fname+'_display'
if hasattr(self, get_choice):
value = getattr(self, get_choice)()
else:
try:
value = getattr(self, fname)
except AttributeError:
value = None
# only display fields with values and skip some fields entirely
if f.editable: # and value:
fields.append(
{
'label':f.verbose_name,
'name':f.name,
'value':value,
'is_editable': f.name in self.editable_field_list
}
)
return fields
template
<ul>
{% for f in object.get_selected_fields %}
<li>{{ f.label|capfirst }} ( {{ f.name }} ) : {{ f.value|escape|urlize }} (editable={{ f.is_editable }})</li>
{% endfor %}
</ul>
必要に応じて、viewの記述も変更
views.py
class UserDetailView(OnlyYouMixin, DetailView):
model = CustomUser
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if int(context["object"].userType.id) == USERTYPE_SUPPLIER:
self.model.viewable_field_list = ('userType', 'username', 'email', 'companyName',)
elif int(context["object"].userType.id) == USERTYPE_BUYER:
self.model.viewable_field_list = ('userType', 'username', 'email', 'nearestStation')
return context
参考