首页 > 解决方案 > Django, exclude from main list, but viewable from django filter

问题描述

I'm trying to add an archive section to my site, though when I say archive, I mean just not visible in the main list view that is the home page, the site is small and the projects are just small amounts of text so space and optimization are never going to be needed. I use django-filter to search through projects by department(Area in my code), and "Archive" is down as one of the departments. I've tried using exclude in the queryset, but of course that just removes any projects with area="Archive" completely so that the "Archive" section is empty. How can I get archived projects removed from the main list view but searchable via the filter.

View:

def project_list_view(request):
    project_list = Project.objects.annotate(
        display_date = models.Case(
            models.When(models.Q(staff_trials__isnull=True) | models.Q(timeline_switch=False), then=models.F('launch')),
            models.When(models.Q(staff_trials__isnull=False) & models.Q(timeline_switch=True), then=models.F('staff_trials')),
            output_field=models.DateField(),
        )
    ).exclude(area='1').order_by('-slip', 'display_date')

    project_filter = ProjectFilter(request.GET, queryset=project_list)
    return render(
        request,
        'project_portal/project_list.html',
        {'filter': project_filter}
        )

filter:

class ProjectFilter(django_filters.FilterSet):

    class Meta:
        model = Project
        fields = ['area', 'user']

For clarity, Area has it's own Model with a foreign key to the Project model, and the departments are just entries in the database. The above code kind of does what I want, but as mentioned before makes archived projects not accessible in any way, whereas I want them to show if "Archive" is picked from the search dropdown.

标签: djangodjango-viewsdjango-filter

解决方案


一种可能的解决方案是仅当过滤器不等于归档时才将其添加exclude到您的查询集中:area

def project_list_view(request):
    project_list = Project.objects.annotate(
        display_date = models.Case(
            models.When(models.Q(staff_trials__isnull=True) | models.Q(timeline_switch=False), then=models.F('launch')),
            models.When(models.Q(staff_trials__isnull=False) & models.Q(timeline_switch=True), then=models.F('staff_trials')),
            output_field=models.DateField(),
        )
    ).order_by('-slip', 'display_date')

    if request.GET.get('area') != '1':
        project_list = project_list.exclude(area='1')

    project_filter = ProjectFilter(request.GET, queryset=project_list)
    return render(
        request,
        'project_portal/project_list.html',
        {'filter': project_filter}
        )

推荐阅读