Reputation: 344
I'm trying to pass an abstract model to an inclusion tag like via takes_context=True
. The abstract model contains choices for a model field. I want to pass the abstract model instead of hardcoding the choices in the template to stay DRY. While debugging I realized that the template isn't receiving the model as expected.
# urls.py
...
urlpatterns = [
path('', IndexView.as_view(), name='index'),
]
# views.py
...
class IndexView(TemplateView):
"""Home Page"""
template_name = 'index.html'
def get_context_data(self, **kwargs):
kwargs['model'] = MyModel
return super(IndexView, self).get_context_data(**kwargs)
...
# index.html
{{model}}
The above renders nothing in the browser. When I change the variable to a string, the context renders as expected.
# views.py
...
class IndexView(BaseSearchBarMixin, TemplateView):
"""Home Page"""
template_name = 'index.html'
def get_context_data(self, **kwargs):
kwargs['model'] = 'testing 123'
return super(IndexView, self).get_context_data(**kwargs)
...
# index.html
{{model}} # fixed typo
# browser
testing 123
I have a feeling I'm doing something stupid but don't know what
EDIT:
Per the accepted answer, passing classes to templates isn't possible. Since the class I wanted to pass is an abstract model, there are cases where MyModel.objects.first()
could return an empty queryset. I ended up making a custom ContextMixin
that added the choices to my class based views.
# myapp.models.users.py
class MyModel(models.Model):
"""shared fields and functions for MyModel models"""
class Meta:
abstract = True
DOWN_VOTE = 'DOWN'
UP_VOTE = 'UP'
VOTE_CHOICES = [
(DOWN_VOTE, 'Down vote'),
(UP_VOTE, 'Up vote'),
]
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
vote = models.CharField(choices=VOTE_CHOICES, default=UP_VOTE, max_length=255)
# views.py
...
class MyModelChoicesContextMixin(ContextMixin):
"""add choices from abstract model to context"""
def get_context_data(self, **kwargs):
"""add choices from abstract model to context"""
context = super(MyModelChoicesContextMixin, self).get_context_data(**kwargs)
context['user_DOWN_vote'] = MyModel.DOWN_VOTE
context['user_UP_vote'] = MyModel.UP_VOTE
return context
class IndexView(MyModelChoicesContextMixin, BaseSearchBarMixin, TemplateView):
"""Home Page"""
template_name = 'index.html'
Upvotes: 0
Views: 58
Reputation: 591
You are passing in a class, not an instance of the class or a queryset, try:
kwargs['model'] = MyModel.objects.first()
(for example - to get the first).
You can't use the class in the template.
Upvotes: 1
Reputation: 3758
In kwargs you are passing keyword 'model' but in template you are using 'Mymodel' keyword that's why empty template is showing.
2nd thing display model fields like model.field_name.
Upvotes: 0