如何在 Django 视图中返回所有不同的外键?

问题描述

这是我的model.py:

class Category(models.Model):
    name = models.CharField(max_length=50,unique=True)
    description = models.CharField(max_length=255,default='')

    def __str__(self):
        return "%s" % (self.name)


class SubCategory(models.Model):
    name = models.CharField(max_length=50,default='')
    category = models.ForeignKey(Category,on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['name']

还有我的 view.py:

def home(request):
    context = {
        'home_page': "active",'categories': SubCategory.objects.order_by('category').distinct('category').values_list('category'),}
    return render(request,'candidates/home.html',context)

和我的模板:

<ul>
        {% for category in categories %}
            <li>{{ category }}</li>
        {% endfor %}
    </ul>

我看到的不是类别名称,而是它们的 ID

enter image description here

我怎样才能得到他们的名字?

谢谢

解决方法

您应该使用类别的名称,因此:

def home(request):
    context = {
        'home_page': "active",'categories': SubCategory.objects.order_by('category__name').distinct('category__name').values_list('category__name',flat=True),}
    return render(request,'candidates/home.html',context)

话虽如此,查询 Subcategory 没有多大意义。您可以通过以下方式获取 Category 列表:

def home(request):
    context = {
        'home_page': "active",'categories': Category.objects.order_by('name'),context)

或者,如果您只想要包含至少一个子类别的 Category,您可以使用:

def home(request):
    context = {
        'home_page': "active",'categories': Category.objects.filter(subcategory__isnull=False).order_by('name').distinct(),context)

您可以通过以下方式简化 __str__Category

class Category(models.Model):
    name = models.CharField(max_length=50,unique=True)
    description = models.CharField(max_length=255,default='')

    def __str__(self):
        return f'{self.name}'

EDIT:您可以按子类别的数量(降序)对 Category 进行排序:

def home(request):
    context = {
        'home_page': "active",'categories': Category.objects.annotate(
            nsub=Count('subcategory')
        ).order_by('-nsub')
    }
    return render(request,context)