Django表单无法在下拉列表中筛选外键

2024-06-16 11:22:20 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:为清晰起见重写说明

我有一个“CustomUser”类,它是从一个全身份验证教程(all auth tutorial (Django All-Auth Tutorial)中获得的,并且我在每个模型中都将user作为外键,它按预期工作,只向该特定用户显示与当前登录用户相关的记录

例如:

教育模式(在这里正确运行)

class Education(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    EducationInstitutionName = models.CharField(verbose_name=_('Institution Name'), max_length=100, default=None)
    EducationLevel = models.CharField(verbose_name=_('Education Level'), choices=EDUCATIONLEVEL, max_length=100, default=None)
    EducationStartDate = models.DateField(verbose_name=_('Education Start Date'), default=None)
    EducationEndDate = models.DateField(verbose_name=_('Education End Date'), default=None)
    EducationCaoCode = models.CharField(choices=CAO_CODE, max_length=100, default=None)
    EducationDesc = models.CharField(verbose_name=_('Education Description'), max_length=250, default=None)


    def __str__(self):
        return self.EducationInstitutionName

这是完美的,我正在实现所需要的

当我有一个由外键组成的表时,问题就出现了。外键是我的应用程序的焦点,它获取CV的组成部分,并允许您将它们组合起来,以生成可交换部分的CV

CV模型(我仅有的由外键组成的模型)

class Cv(models.Model):
    user = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
    )
    CvName = models.CharField(verbose_name=_('CvName'), max_length=100, default=None)
    CvEducation = models.ForeignKey(Education, on_delete=models.CASCADE)
    CvSkills = models.ForeignKey(Skills, on_delete=models.CASCADE)
    CvWorkExperience = models.ForeignKey(WorkExperience, on_delete=models.CASCADE)

    def __str__(self):
        return self.CvName

简历表

这就是我要解决的问题所在-我想过滤字段,只显示当前用户的教育、技能和工作经验记录-此时下拉列表显示教育、技能和工作经验模型的所有记录,而不是仅与当前登录用户相关的记录

class CvForm(forms.ModelForm):
    class Meta:
        model = Cv
        fields = ('CvName', 'CvEducation', 'CvSkills', 'CvWorkExperience')

# TRYING TO FILTER BY CURRENT USER
    def __init__(self, user, *args, **kwargs):
        super(CvForm, self).__init__(*args, **kwargs)
        print(user)
        self.fields['CvEducation'].queryset = Education.objects.filter(user=user)
        self.fields['CvSkills'].queryset = Education.objects.filter(user=user)
        self.fields['CvWorkExperience'].queryset = Education.objects.filter(user=user)


    def save(self, commit=True):
        cv = super(CvForm, self).save(commit=False)
        cv.user = self.request.user
        cv.CvName = self.cleaned_data['CvName']
        cv.CvEducation = self.cleaned_data['CvEducation']
        cv.CvSkills = self.cleaned_data['CvSkills']
        cv.CvWorkExperience = self.cleaned_data['CvWorkExperience']
        cv.save()
        return cv

简历列表视图(此视图-正确-仅显示与当前登录用户关联的已完成的简历记录)

class CvList(ListView):
    model = Cv
    fields = ['CvName', 'CvEducation', 'CvSkills', 'CvWorkExperience']
    success_url = reverse_lazy('Cv_list')

    def get_queryset(self):
        user_ids = CustomUser.objects.filter(username=self.request.user).values_list('id', flat=True)
        if user_ids:
            for uid in user_ids:
                return Cv.objects.filter(user__id=uid)
        else:
            return Cv.objects.all()

CV创建视图

class CvCreate(CreateView):
    model = Cv
    fields = ['CvName', 'CvEducation', 'CvSkills', 'CvWorkExperience']
    success_url = reverse_lazy('Cv_list')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(CvCreate, self).form_valid(form)

    def get_queryset(self):
        user_ids = CustomUser.objects.filter(username=self.request.user).values_list('id', flat=True)
        if user_ids:
            for uid in user_ids:
                return Cv.objects.filter(user__id=uid)
        else:
            return Cv.objects.all()

这让我。。。 Dropdown showing the whole Education table rather than filtering by Current User

在这张图像中,当我以John Doe的身份登录时,我应该无法看到记录-“James Edu”,因为它与另一个用户相关

这发生在我使用外键的所有三个领域——CvEducation、CvSkills和CvWorkExperience


Tags: selfnonedefaultreturnobjectsmodelsdefcv
1条回答
网友
1楼 · 发布于 2024-06-16 11:22:20

最终修复(以非常迂回的方式):

表单初始化方法

 def __init__(self, *args, **kwargs):
        initial_arguments = kwargs.get('initial', None)
        initial_arguments_list = list(initial_arguments.values())
        user_id = initial_arguments_list[0]
        super(CvForm, self).__init__(*args, **kwargs)
        self.fields['CvEducation'].queryset = Education.objects.filter(user__id=user_id)
        self.fields['CvSkills'].queryset = Skills.objects.filter(user__id=user_id)
        self.fields['CvWorkExperience'].queryset = WorkExperience.objects.filter(user__id=user_id)

创建视图

class CvCreate(CreateView):
    model = Cv
    success_url = reverse_lazy('Cv_list')
    form_class = CvForm
    exclude = ['user']

    def get_initial(self):
        self.initial.update({ 'created_by': self.request.user.id })
        return self.initial

相关问题 更多 >