Sahil
Sahil

Reputation: 1413

Unable to display data from model in template

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

Answers (3)

KIRUTHIKA S
KIRUTHIKA S

Reputation: 1

{% block content %}

{{ object.title }}

<h6> on {{ object.datetime }}</h6>

<div class = "code">
    {{ object.content|linebreak }}
</div>

{% endblock %}

Upvotes: 0

seuling
seuling

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

neverwalkaloner
neverwalkaloner

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

Related Questions