How to refer to an inherited model in django

Question:

As in the title, that is, how to refer to an inherited model in django. I’m struggling with using the model_name function which returns the model name but it’s not going the way I’d like.

models.py

class Product(PolymorphicModel):
    title = models.CharField(max_length=100, blank=True)
    image = models.ImageField(upload_to='product', default=None)
    quantity = models.IntegerField(null=False)
    is_available = models.BooleanField(default=True, null=False)
    price = models.IntegerField(null=False, blank=False, default=15)
    popularity = models.IntegerField(default=0)

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

    def get_absolute_url(self):
        return reverse("ProductDetail", args=[str(self.pk)])

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




class CD(Product):
    GENRE_CHOICES = (
        ('Disco', 'Disco'),
        ('Electronic music', 'Electronic music'),
        ('Rap', 'Rap'),
        ('Reggae', 'Reggae'),
        ('Rock', 'Rock'),
        ('Pop', 'Pop'),
    )
    band = models.CharField(max_length=100, null=False, blank=False)
    tracklist = models.TextField(max_length=500, null=False, blank=False)
    genre = models.CharField(max_length=100, choices=GENRE_CHOICES, null=False, blank=False)


class Book(Product):
    GENRE_CHOICES = (
        ('Biography', 'Biography'),
        ('Criminal', 'Criminal'),
        ('Fantasy', 'Fantasy'),
        ('Historical Novel', 'Historical Novel'),
        ('Horror', 'Horror'),
        ('Romance', 'Romance'),
        ('Sci-Fi', 'Sci-Fi'),
    )
    author = models.CharField(max_length=100, null=False, blank=False)
    isbn = models.CharField(max_length=100, null=False, blank=False, unique=True)
    genre = models.CharField(max_length=100, choices=GENRE_CHOICES, null=False, blank=False)


class Film(Product):
    GENRE_CHOICES = (
        ('Adventure', 'Adventure'),
        ('Animated', 'Animated'),
        ('Comedy', 'Comedy'),
        ('Horror', 'Horror'),
        ('Thriller', 'Thriller'),
        ('Romance', 'Romance'),
    )
    director = models.CharField(max_length=100, null=False, blank=False)
    duration = models.IntegerField(null=False, blank=False)
    genre = models.CharField(max_length=100, choices=GENRE_CHOICES, null=False, blank=False)

views.py

class Statistics(ListView):
    model = Product
    template_name = 'orders/statistics.html'

    def get_queryset(self):
        qs = super(Statistics, self).get_queryset()
        if self.request.GET:
            qs = qs.filter(model_name=self.request.GET['category'])
        return qs

    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        data['form'] = CategoryForm
        return data

forms.py

from django import forms


class CategoryForm(forms.Form):
    CATEGORY_CHOICES = (
        ('book', 'Book'),
        ('cd', 'CD'),
        ('film', 'Film'),
    )

    category = forms.ChoiceField(choices=CATEGORY_CHOICES)

html

{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for item in object_list %}
    <form method="get">
        {{ form }}
        <input type="submit" value="Search">
    </form>

    <table>
        <tr>
            <th>Title</th>
            <th>Category</th>
            <th>Genre</th>
            <th>Popularity</th>
        </tr>
        <tr>
            <td>{{ item.title }}</td>
            <td>{{ item.model_name}}</td>
            <td>{{ item.genre }}</td>
            <td>{{item.popularity}}</td>
        </tr>
    </table>
{% endfor %}
{% endblock %}

I would like to use the value in GET to select which product to display and substitute in get_queryset()

Asked By: Tylzan

||

Answers:

You can try to fetch the class object in your get_queryset() and then use the filter() or all() directly on that Model:

def get_queryset():
    from django.apps import apps

    if self.request.GET:
        my_model = apps.get_model(app_label="your_app_name", model_name=self.request.GET["category"])
        return my_model.objects.all()
    return super(Statistics, self).get_queryset()
Answered By: Eliu S
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.