Here's a code example :
class ResourceBase(models.Model):
categories = [
("podcast", "Podcast"),
("shop", "Shop"), #etc
]
name = models.CharField(max_length=255)
description = models.TextField()
category = models.CharField(max_length=32, choices=categories)
class Meta:
abstract = True
def __str__(self):
return f"{self.category} - {self.name}"
class Podcast(ResourceBase):
def save(self, *args, **kwargs):
if not self.pk:
self.category = "podcast"
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("resources:podcast", kwargs={"pk": self.pk})
class Shop(ResourceBase):
def save(self, *args, **kwargs):
if not self.pk:
self.category = "shop"
self.phone = self.phone.replace(" ", "")
super().save(*args, **kwargs)
city = models.CharField(max_length=128)
address = models.CharField(max_length=255)
phone = models.CharField(max_length=32)
def get_absolute_url(self):
return reverse("resources:shop", kwargs={"pk": self.pk})
# etc
Because I can't request an absctract model to get all the "resources", here is a more elegant way to objects.all() my ResourceBase model instead of list(chain(podcasts, shops in my view.
def get_last_resources(request):
podcasts = Podcast.objects.all().order_by("-created_at")[:5]
shops = Shop.objects.all().order_by("-created_at")[:5] #etc
resources = list(chain(podcasts, shops, websites, discord_servers))
resources = sorted(resources, key=lambda x: x.created_at, reverse=True)
context = {"last_resources": resources}
return render(request, "resources/last_resources.html", context)
Thanks.