如何在Django中对其自身的模型进行两次过滤?

时间:2019-09-18 09:01:15

标签: python django django-models django-templates django-views

我正在寻找一些有关在Django中两次过滤模型的帮助。

这是我当前的模型:

class Medarbejder(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField(max_length=200)
    ma = models.IntegerField(help_text="Indtast medarbejderens MA-nummer. (F.eks 123456)")
    fornavn = models.CharField(max_length=30, help_text="Indtast medarbejderens fornavn.")
    efternavn = models.CharField(max_length=30, help_text="Indtast medarbejderens efternavn.")
    holdnavn = models.CharField(max_length=200, null=False, help_text="Indtast medarbejderens hold.")
    delingnavn = models.ForeignKey('Deling', on_delete=models.CASCADE, null=True)
    fagnavn = models.ForeignKey('Fag', on_delete=models.CASCADE, null=True)

该模型是员工(medarbejder)的模型。现在,我希望用唯一的过滤团队名称(holdnavn),这已完成。下一步是过滤每个小组名称(holdnavn)中的所有部门(delingnavn)。因此,当我单击一个团队名称(例如“ GSU19”)时,我希望仅获得该团队名称中所有部门的列表。

我似乎不知道该怎么做?我可以使用slug和pk来做到这一点,但是teamname和department都不是slug或pk,因此我对如何获取url中的值并再次过滤感到迷茫。

这是我单击特定团队名称后URL的外观:

http://127.0.0.1:8000/hold/%3CQuerySet%20%5B%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%204%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%205%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%206%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%202%7D,%20%7B'delingnavn_id':%203%7D,%20%7B'delingnavn_id':%203%7D%5D%3E/

我在url中获取所有部门ID。这不是我想要的,我希望它们在我的模板中循环显示。下面是我当前的ListView:

class HoldDetailView(ListView):
    model = Medarbejder
    template_name = 'evalsys/medarbejder/list.html'

    def get_context_data(self, **kwargs):
        context = super(HoldDetailView, self).get_context_data(**kwargs)
        context['medarbejder_hold'] = Medarbejder.objects.filter().values('holdnavn').distinct().order_by('holdnavn')
        context['medarbejder_deling'] = Medarbejder.objects.filter().values('delingnavn_id').distinct()
        return context

    def get_object(self, holdnavn=None):
        if holdnavn:
            medarbejder_deling = Medarbejder.objects.filter().values('delingnavn_id').distinct()
        else:
            medarbejder_deling = self.medarbejder_deling
        return render(self, 'evalsys/medarbejder/list.html',
                      { 'medarbejder_deling': medarbejder_deling})

请提出任何问题,我将提供更多代码,我认为我的方法是错误的,但是我似乎无法弄清楚该怎么做。

为澄清起见:

Delingnavn = DepartmentName,是Departments的外键。

Holdnavn = TeamName

Fornavn =名字

Efternavn =姓氏

FagNavn = SubjectName

我希望获得所有团队名称,单击一个,然后查看该团队中的所有部门。

更新

在模板中:

        {% for h in medarbejder_hold %}
            <li>
                <a href="{% url 'evalsys:get_object' holdnavn=medarbejder_deling  %}">{{ h.holdnavn }} </a>
            </li>
        {% endfor %}

我这样做是因为通常我会使用或pk ...

URL:

path('', views.HoldDetailView.as_view(), name='home'),
path('hold/<str:holdnavn>/', views.HoldDetailView.as_view(), name='get_object'),

1 个答案:

答案 0 :(得分:0)

不幸的是,此代码无处不在。 get_object从来没有在ListView中被调用过,这也是一样。您无法在该方法内进行渲染,而是用于返回 object 。就像我说的那样,URL本身是胡说八道,您不能期望仅将查询集转储到URL中。

但是不清楚为什么您认为需要执行这两个操作。如果要按特定的holdnavn进行过滤,则只需将该值传递到URL中并进行适当的过滤即可。 (请注意,我已经更改了获取holdavn列表的方式,以使事情变得简单一些。)

    {% for holdnavn in medarbejder_hold %}
        <li>
            <a href="{% url 'evalsys:get_object' holdnavn=holdnav %}">{{ holdnavn }} </a>
        </li>
    {% endfor %}

class HoldListView(ListView):
    model = Medarbejder
    template_name = 'evalsys/medarbejder/list.html'
    context_object_name = 'medarbejder_deling'

    def get_context_data(self, **kwargs):
        context = super(HoldDetailView, self).get_context_data(**kwargs)
        context['medarbejder_hold'] = Medarbejder.objects.filter().values_list('holdnavn').distinct().order_by('holdnavn')
        return context

    def get_queryset(self):
       qs = super().get_queryset()
       if 'holdavn' in self.kwargs:
           qs = qs.filter(holdavn=self.kwargs['holdavn'])
       return qs