Kye
Kye

Reputation: 4504

Access model name in Django CreateView from template

I'm using the generic CRUD views in Django 1.6, e.g.:

class KanriCreateView(CreateView):
    template_name = 'generic_form.html'

class KanriUpdateView(UpdateView):
    template_name = 'generic_form.html'

etc.

N.B. These are classes used as a base class which I subclass inside views.py files throughout the project.

In order to keep DRY I'm writing a generic form template for all create/update views.

For update views, I have access to object in the template, which is the instance I am updating. I then use object.__class__.__name__ (via a custom filter) to get the name of the class (so I can have automatically generated custom buttons like "Add User", "Add Role".etc so the forms look less...generic.

Of course, when I'm using my template in CreateView, object does not exist (as it has not been created), so my custom buttons.etc do not work, and I get a VariableDoesNotExist exception.

Does Django provide the class somewhere so I can use it in the template?

Upvotes: 1

Views: 1954

Answers (3)

Claudio Finizio
Claudio Finizio

Reputation: 21

I propose a solution updated for Django 2 and 3: retrieve the model verbose name from the ModelForm associated to the CreateView.

class YourCreateView(CreateView):

    form_class = YourModelForm

    def get_context_data(self, **kwargs):
        """Add the models verbose name to the context dictionary."""

        kwargs.update({
            "verbose_name": self.form_class._meta.model._meta.verbose_name,})
        return super().get_context_data(**kwargs)

Now you can use {{ verbose_name }} inside your template.

Please, remark the double _meta in the code snippet above: the first is meant to access the model from the ModelForm, while the second accesses the verbose name of the Model.

As with internationalization, remark that if your model uses ugettext as shown below, then the verbose name will automatically be translated in the template.

from django.utils.translation import ugettext_lazy as _

class MyModel(models.Model):
    class Meta:
        verbose_name = _("your verbose name")

Upvotes: 0

Ben
Ben

Reputation: 198

If you're using a ModelForm for your CreateView, this doesn't quite work. This is because you're not specifying

model = MyModel

but instead you're specifying

form_class = MyModelForm

so what you can do instead is

from django.contrib.admin.utils import model_ngettext

model_ngettext(self.form_class._meta.model, 1)

Upvotes: 0

Malte Jacobson
Malte Jacobson

Reputation: 225

  1. The name of your first view should be different, e.g. KanriCreateView
  2. It might help you to get the name of the view class: {{ view.class.name }}
  3. If you have access to the view class (which is provided by default by the ContextDataMixin) you can access the model attribute of the view class and get the name of the model: {{ view.model.__name__ }}

Cheers

Upvotes: 2

Related Questions