Home > OS >  Custom Mixin to get verbose name not rendering when called in Django DetailView
Custom Mixin to get verbose name not rendering when called in Django DetailView

Time:11-13

I have created a custom mixin GetVerboseNameMixin in order to get the verbose name of model fields, and then display these in my html template using a DetailView. However, whenever I try and render the list of verbose names nothing is returned, and I cannot work out why.

Mixin.py:

class GetVerboseNameMixin:
    def get_verbose_name(model, fields=[]):
        verbose_names = []
        for field in fields:
            verbose_names.append(str(model._meta.get_field(field)))
        return verbose_names

View:

class ShowProfileView(GetVerboseNameMixin, DetailView):
    model = Profile
    template_name = 'profiles/user_profile.html'
    verbose_model_fields = GetVerboseNameMixin.get_verbose_name(model=Profile, fields=['first_name', 'surname', 'date_of_birth', 'phone_number', 'bio', 'gender', 'emergency_contact_name', 'emergency_contact_number'])



    def get_context_data(self, *args, **kwargs):
        context = super(ShowProfileView, self).get_context_data(*args, **kwargs)
        user_profile = get_object_or_404(Profile, id=self.kwargs['pk']) 
        context["user_profile"] = user_profile
        return context

    def get_object(self, *args, **kwargs):
        obj = Profile.objects.filter(id=self.kwargs['pk']).values('first_name', 'surname', 'date_of_birth', 'phone_number', 'bio', 'gender', 'emergency_contact_name', 'emergency_contact_number') # list of dictionaries
        object = obj[0]
        return object

Html template:

{% extends "base.html" %}

{% block content %}

    <h1>Profile</h1>
    <br/><br/>
    {% csrf_token %}
    <ul>
    {% for v in object.values %}
    {% for field_name in verbose_model_fields %}
    <p>{{field_name}}: {{ v }}</p>
    {% endfor %}
    {% endfor %}
    </ul>
    <a href='{% url "profiles:edit_profile" pk=user.profile.id %}'>Edit Profile</a>


{% endblock %}

Even if I just render:

{{ verbose_model_fields }}

In my html file nothing is being displayed. This leads me to think maybe the problem is in my mixin, or perhaps the function is not being called properly?

CodePudding user response:

I do not get how verbose_model_fields is getting passed to the template from the view, and also, I did not find any reference in DetailView documentation. I assume you want to have this custom implementation, if so, then you need to pass along this parameter via context:

class ShowProfileView(GetVerboseNameMixin, DetailView):
    ...

    def get_context_data(self, *args, **kwargs):
        context = super(ShowProfileView, self).get_context_data(*args, **kwargs)
        user_profile = get_object_or_404(Profile, id=self.kwargs['pk']) 
        context["user_profile"] = user_profile  # redundant implementation, you can get this value by `object` context variable in template
        context["verbose_model_fields"] = self.verbose_model_fields  # or just call self.get_verbose_name(...) method
        return context

Also in this solution I have marked redundant implementation that you do not need to re-implement how to get object, because it is already taken care by DetailView.

  • Related