简体   繁体   中英

Models not rendering in Django templates

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM