Django在下拉菜单中显示主题的唯一列表(许多)

我希望能够在模板中产生一个带有唯一主题列表的下拉菜单。

对象填充在管理员内部,而不是在SUBJECT_CHOICES中对其进行硬编码。

一门课程可以有许多科目,也可以只有1门科目。例如:

课程标题= Django 主题=技术

课程标题= Python 主题=技术

课程标题=会计 主题=商业

课程标题=电子商务 主题=技术,商业

CourseListView对应于course_list.html模板。

models.py

class Subject(models.Model):
    SUBJECT_CHOICES = ()
    name = models.CharField(max_length=20,choices=SUBJECT_CHOICES,unique=True)

    def __str__(self):
        return self.name

class Course(models.Model):
​
    SKILL_LEVEL_CHOICES = (
        ('Beginner','Beginner'),('Intermediate','Intermediate'),('Advanced','Advanced'),)
​
    slug = models.SlugField()
    title = models.CharField(max_length=120)
    description = models.TextField()
    allowed_memberships = models.ManyToManyField(Membership)
    created_at = models.DateTimeField(auto_now_add=True)
    subjects = models.ManyToManyField(Subject)
    skill_level = models.CharField(max_length=20,choices=SKILL_LEVEL_CHOICES,null=True)
    visited_times = models.IntegerField(default=0)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('courses:detail',kwargs={'slug': self.slug})

    @property
    def lessons(self):
        return self.lesson_set.all().order_by('position')

views.py

class CourseListView(ListView):
    model = Course
    def get_queryset(self):
        qs = super().get_queryset()
        title_contains_query = self.request.GET.get('title_contains')
        view_count_min = self.request.GET.get('view_count_min')
        view_count_max = self.request.GET.get('view_count_max')
        date_min = self.request.GET.get('date_min')
        date_max = self.request.GET.get('date_max')
        skill_level_query = self.request.GET.get('skill_level')
        if title_contains_query:
            qs = qs.filter(title__icontains=title_contains_query)
        if view_count_min:
            qs = qs.filter(visited_times__gte=view_count_min)
        if view_count_max:
            qs = qs.filter(visited_times__lte=view_count_max)
        if date_min:
            qs = qs.filter(created_at__gte=date_min)
        if date_max:
            qs = qs.filter(created_at__lte=date_max)
        if skill_level_query:
            qs = qs.filter(skill_level=skill_level_query)
        return qs

所需的输出:

Django在下拉菜单中显示主题的唯一列表(许多)

我尝试在模板中编写一个for循环,该循环确实成功返回了主题,但它们不是唯一的或仅显示一次。

{% for item in object_list %}
<h2>{{ item.subjects.all}}</h2>
<ul>
    {% for sub in item.subjects.all %}
    <li><a href="#" id="">{{ sub.name }}</a></li>
    {% endfor %}
</ul>
{% endfor %}

结果:

<QuerySet [<Subject: Business>]>
Business
<QuerySet [<Subject: Technology>]>
Technology
<QuerySet [<Subject: Technology>]>
Technology
<QuerySet [<Subject: Business>]>
Business

我更喜欢使用for循环来产生唯一的结果,但是也许可以用django-select2来完成,或者使用带有模型选择或多个模型选择的表单?有人可以为循环或这些方法之一提供一些代码吗?

对此我将不胜感激。

hank112 回答:Django在下拉菜单中显示主题的唯一列表(许多)

我在这里看到两种解决方案:

第一个是简单地获取Subject模型中的所有输入值,但您不能使用视图中正在使用的所有过滤器,只能使用与标题有关的所有过滤器。

为此,只需使用:

title_contains_query = self.request.GET.get('title_contains')
if title_contains_query:
    subjects = [title for title in Subject.objects.filter(title__icontains=title_contains_query)]

另一种选择是在QuerySet上使用distinct()方法,该方法可以过滤并删除其中的重复条目。像这样使用它:qs = qs.distinct()

希望有帮助!

本文链接:https://www.f2er.com/3084708.html

大家都在问