如何根据Django中的用户从CreateView中删除字段?

时间:2018-03-28 13:01:41

标签: python django django-class-based-views form-fields class-based-views

我创建了一个CBV,我想删除一个或多个字段,具体取决于用户。这个想法是一个工作现场,如果登录用户是招聘人员,那么应该包括class JobCreationForm(forms.ModelForm): class Meta: model = Job # exclude = ['posted', 'provider', 'ext_id'] fields = ('title', 'job_desc', 'agency_name', 'employer', 'contact_name', ) 字段,否则应该将其排除在外。

forms.py

class JobCreateView(LoginRequiredMixin, CreateView): 
    template_name = 'job/job.html'
    form_class = JobCreationForm
    success_url = '/'

    def get_context_data(self, **kwargs):
        context = super(JobCreateView, self).get_context_data(**kwargs)
        # import the Customers of this Company
        self.fields["agency_name"].remove()
        recruiter = self.request.user
        self.fields["contact_name"].queryset = Profile.objects.filter(user_id = self.request.user)
        # if the user is a recruiter, delete the employer field.
        if Company.objects.filter(user_id = self.request.user).values('is_recruiter') == False:
            pass
            # self.fields.remove("employer")
            del self.fields["employer"]
        return context

views.py

NoneType' object has no attribute '__getitem__'

当前错误为self.fields["employer"].delete()

我的问题:如何根据逻辑从表单中删除字段?我试过这些版本:

  • self.fields.remove("employer")
  • del self.fields["employer"]
  • const response = yield call(getCharacters, accessToken)

任何提示?

3 个答案:

答案 0 :(得分:3)

实现此目的的正确方法(根据用户修改表单的字段)是在表单__init__方法上执行此操作。但是,为了使表单能够访问当前用户,您需要从视图中将用户传递给它。为此,您将使用get_form_kwargs方法。因此,首先在视图中添加以下方法:

def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()
    kwargs.update({'user': self.request.user})
    return kwargs

现在,您可以在表单中添加__init__,如下所示:

def __init__(self, *args, **kwargs):
    self.user = kwargs.pop('user', None)
    super().__init__(*args, **kwargs)

    if Company.objects.filter(user_id = self.user).is_recruiter == False:
        self.fields.pop("employer")
        self.fields.pop('owned_by')

请注意,您首先初始化表单(使用super.__init__),然后您可以将字段修改为您心中的内容。

答案 1 :(得分:2)

有很多方法可以解决这个问题。

我发现有两个单独的表单RecruiterEmployeeFormEmployeeForm可能更整洁。

class RecruiterEmployeeForm(forms.ModelForm):
    model = Job
    fields = ('title',
              'job_desc', 
              'agency_name',
              'employer', 
              'contact_name',
    )

class EmployeeForm(forms.ModelForm):
    model = Job
    fields = ('title',
              'job_desc', 
              'agency_name',
              'contact_name',
    )

然后你可以覆盖CBV的ger_form_class

def get_form_class(self):
    if self.request.user.is_recruiter():
        return RecruiterEmployeeForm
    else:
        return EmployeeForm

答案 2 :(得分:1)

要发送额外的kwargs以使用通用视图方法get_form_kwargs,并获取额外的kwargs覆盖__init__表单和pop额外的kwargs。

forms.py

class JobCreationForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
         user = kwargs.pop('user', None)
         super(JobCreationForm, self).__init__(*args, **kwargs)

        if Company.objects.filter(user_id = self.user).is_recruiter == False:
            self.fields.pop("employer")

    class Meta:
        model = Job
        # exclude = ['posted', 'provider', 'ext_id']
        fields = ('title', 'job_desc', 'agency_name', 'employer',  'contact_name')

views.py

class JobCreateView(LoginRequiredMixin, CreateView): 
    template_name = 'job/job.html'
    form_class = JobCreationForm
    success_url = '/'

    def get_form_kwargs(self):
      kwargs = super(JobCreateView, self).get_form_kwargs()
      kwargs.update({'user': self.request.user})
      return kwargs