Reputation: 1413
I am trying to display data from a model inside my post.html
which worked before but now dosen't for some reason I can't figure out.
urls.py
urlpatterns = [
path('', ListView.as_view(
queryset=Tutorials.objects.all().order_by("-date")[:25],
template_name="tutorials/blog.html"
)),
path('<int:pk>', DetailView.as_view(
model=Tutorials,
template_name="tutorials/post.html")),
]
blog.html
{% block python %}
{% for Tutorials in object_list %}
{% if Tutorials.categories == "pythonbasics" %}
<a href="/tutorials/{{ Tutorials.id }}"><h1>{{ Tutorials.title }}</h1></a>
<br>
Created On : {{ Tutorials.date|date:"Y-m-d" }}
{% endif %}
{% endfor %}
{% endblock %}
post.html
{% block content %}
<h3>{{ Tutorials.title }}</h3>
<h6> on {{ Tutorials.datetime }}</h6>
<div class = "code">
{{ Tutorials.content|linebreaks }}
</div>
{% endblock %}
Upvotes: 1
Views: 60
Reputation: 1
{% block content %}
<h6> on {{ object.datetime }}</h6>
<div class = "code">
{{ object.content|linebreak }}
</div>
{% endblock %}
Upvotes: 0
Reputation: 2966
plus for @neverwalkaloner's answer.
The reason why you can use object
or context_object_name
is cause you inherit DetailView
.
In DetailView
, it has get_object()
method.
def get_object(self, queryset=None):
"""
Return the object the view is displaying.
Require `self.queryset` and a `pk` or `slug` argument in the URLconf.
Subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg)
slug = self.kwargs.get(self.slug_url_kwarg)
if pk is not None:
queryset = queryset.filter(pk=pk)
# Next, try looking up by slug.
if slug is not None and (pk is None or self.query_pk_and_slug):
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
# If none of those are defined, it's an error.
if pk is None and slug is None:
raise AttributeError("Generic detail view %s must be called with "
"either an object pk or a slug."
% self.__class__.__name__)
try:
# Get the single item from the filtered queryset
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return obj
It will return model object, and also you can override this method.
And in get()
method in DetailView
,
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
As you see, it define self.object
to self.get_object()
so you can use self.object
inside DetailView
.
Finally, you can use object
in your template because of get_context_data()
.
DetailView
basically add 'object' to context, so you can use it.
def get_context_data(self, **kwargs):
"""Insert the single object into the context dict."""
context = {}
if self.object:
context['object'] = self.object
context_object_name = self.get_context_object_name(self.object)
if context_object_name:
context[context_object_name] = self.object
context.update(kwargs)
return super().get_context_data(**context)
It's true that CBV has little bit learning curve, but when you see django source code and read about docs, it's easy to follow.
+I highly recommend ccbv.co.kr - you can see which view and mixin that CBV inherit, and it's methods too.
Upvotes: 1
Reputation: 47374
You should use object
name in template:
{% block content %}
<h3>{{ object.title }}</h3>
<h6> on {{ object.datetime }}</h6>
<div class = "code">
{{ object.content|linebreaks }}
</div>
{% endblock %}
Or if you want to use Tutorial
variable, you need to pass context_object_name=Tutorials
to the view:
path('<int:pk>', DetailView.as_view(
model=Tutorials,
template_name="tutorials/post.html",
context_object_name='Tutorials')),
Upvotes: 2