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'
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.