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()
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()
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()
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()