Home > database >  How to display name of table from queryset in django
How to display name of table from queryset in django

Time:01-11

Trying to get the table name in django, I need it to display the detailview correctly via if statemnet. I have such a view to display

class Home(ListView):
    template_name = 'home.html'
    def get_queryset(self):
        qs1 = Book.objects.all()
        qs2 = CD.objects.all()
        qs3 = Film.objects.all()
        queryset = sorted(list(chain(qs1, qs2, qs3)), key=operator.attrgetter('title'))
        return queryset

and it returns to me this

[<CD: Music1>, <CD: Music2>, <Book: Some books>]

How can I get "CD" or "Book" in this template

{% block content %}
<div >
{% for object in object_list %}
    <div >
        <div >
            <img src="{{ object.image.url }}">
            <a href="{% url 'DetailBook' object.pk %}" >{{ object.title }}</a>
        </div>
    </div>
{% endfor %}
</div>
{% endblock content %}

At the same time, if it's a bad idea to display detailview and listview and it's done differently, I'd appreciate it if you'd let me know

I tried different ways of displaying object.key in a loop but it didn't work very well. And other queryset queries.

CodePudding user response:

I've been down the list(chain(ob1, ob2, .. obn) route. It proved highly tedious from a standpoint of code maintainability and complexity. Django Polymorphic is the way to go here.

from polymorphic.models import PolymorphicModel

class Product(PolymorphicModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='products')
    title = models.CharField(max_length=100)
    slug = ...
    ... more fields all products share ex: price

    def __str__(self):
        return str(self.title)

    @property
    def model_name(self):
        return self._meta.model_name

class Cd(Product):
    <model fields for CD model>

class Book(Product):
    <model fields for book model>

class Film(Product):
    <model fields for film model>

Then:

Product.objects.all()

Will return the instances of all CD, Book and Film objects.

In your template, you can use the property model_name to check if the object is a certain type of model.

{% block content %}
<div >
{% for object in object_list %}
    {% if object.model_name == 'book' %}
    <div >
        <div >
            <img src="{{ object.image.url }}">
            <a href="{% url 'DetailBook' object.pk %}" >{{ object.title }}</a>
        </div>
    </div>
    {% endif %}
{% endfor %}
</div>
{% endblock content %}

CodePudding user response:

You can obtain this with the .verbose_name attribute [Django-doc] of the model options, so my_object._meta.verbose_name. There is however a problem here: you can not access variables that start with an underscore, since these are "protected" or "private".

A solution might be to work with a template filter. You can define a templatetags directory:

app_name/
    __init__.py
    models.py
    templatetags/
        __init__.py
        model_utils.py
    views.py

where you create the files in boldface. In model_utils, you can construct a filter with:

from django import template

register = template.Library()


@register.filter
def modelname(value):
    return value._meta.verbose_name

then we can use these in the template with:

{% load model_utils %}

{% for object in object_list %}
    …
    {{ object|modelname }}
{% endfor %}
  • Related