Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将CreateView中的表单字段限制为不将当前用户显示为模板中的选项_Python_Django_Dictionary_Django Views_Django Class Based Views - Fatal编程技术网

Python 将CreateView中的表单字段限制为不将当前用户显示为模板中的选项

Python 将CreateView中的表单字段限制为不将当前用户显示为模板中的选项,python,django,dictionary,django-views,django-class-based-views,Python,Django,Dictionary,Django Views,Django Class Based Views,我使用简单的表单和通用的CBV更新视图让所有用户使用“令牌”来给其他用户额外的积分。用户不应该被允许给自己额外的积分,所以他们不应该出现在选择字段中作为选择。我在这里没有使用模型表单,我想知道如何在不使用模型表单的情况下执行此操作。以下是我迄今为止的代码: models.py class ExtraCredit(models.Model): recipient = models.ForeignKey(Developer, related_name='extracredit_recipie

我使用简单的表单和通用的CBV更新视图让所有用户使用“令牌”来给其他用户额外的积分。用户不应该被允许给自己额外的积分,所以他们不应该出现在选择字段中作为选择。我在这里没有使用模型表单,我想知道如何在不使用模型表单的情况下执行此操作。以下是我迄今为止的代码:

models.py

class ExtraCredit(models.Model):
    recipient = models.ForeignKey(Developer, related_name='extracredit_recipient')
    sender = models.ForeignKey(Developer, related_name='extracredit_sender')
    skill = models.ForeignKey(Skill, related_name='extracredit_skill')
    description = models.TextField(blank=True, null=True)
    date_credited = models.DateField(auto_now_add=True)

    def __str__(self):
        return '%s %s -> %s %s - %s' % (self.sender.user.first_name, self.recipient.user.last_name, self.recipient.user.first_name, self.recipient.user.last_name, self.skill.name)
views.py

class ExtraCreditCreateView(CreateView):
    model = ExtraCredit
    template_name = 'extracredit_create.html'

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

        self.fields['recipient'].queryset = ExtraCredit.objects.exclude(recipient=user)
        self.fields['description'].help_text = "Why does this user deserve extra credit?"

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

    def get_success_url(self):
        return reverse('my_developer_details')

    def form_invalid(self, form):
        return self.render_to_response(self.get_context_data(form=form))

    def form_valid(self, form):
        form.save(commit=False)
        sender = get_object_or_404(Developer, user_id=self.request.user.id)
        extra_credit_tokens = Developer.objects.get(user_id=sender.user_id).extra_credit_tokens

        if extra_credit_tokens:
            Developer.objects.filter(user_id=sender.user_id).update(extra_credit_tokens=extra_credit_tokens-1)

            form.instance.sender = sender
            form.save()

            return super(ExtraCreditCreateView, self).form_valid(form)
        else:
            raise forms.ValidationError("The user does not have enough tokens")

    fields = ['recipient', 'skill', 'description']
我使用
get\u form\u kwargs(self)
函数的唯一原因是尝试在
def\u init\u
函数中使用
self.request.user
。如果在
函数中使用self.request.user,我会得到一个错误,即请求不是
ExtraCreditCreateView
的属性。如果我将request添加到选项中,比如
\uuuu init\uuuu(self、request、*args、**kwargs):
那么我会得到一个错误,即需要两个参数而只提供一个参数。按照现在的设置方式,我得到一个类型错误:
列表索引必须是整数,而不是str

在模板中创建表单时,如何确保当前登录用户不在“收件人”字段中

更新的解决方案(基于@Alasdair的答案):


您说希望避免定义模型表单,但这是最好的方法。可以在方法中对表单的字段进行黑客攻击,但不应该这样做

设置收件人的查询集属于表单,而不是视图的
\uuuu init\uuu
方法

class ExtraCreditForm(forms.ModelForm):

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

        self.fields['recipient'].queryset = ExtraCredit.objects.exclude(recipient=user)
        self.fields['description'].help_text = "Why does this user deserve extra credit?"
然后从视图中删除
\uuuu init\uuu
方法,并设置
form\u class
,使其使用您的模型表单。您已经更新了
get\u form\u kwargs
以将用户传递到表单的
\uuuu init\uuu
方法,因此不必进行任何其他更改。您的
表单\u invalid
方法没有执行任何特殊操作,因此您可以将其删除

class ExtraCreditCreateView(CreateView):
    form_class = ExtraCreditForm
    ...

您说希望避免定义模型表单,但这是最好的方法。可以在方法中对表单的字段进行黑客攻击,但不应该这样做

设置收件人的查询集属于表单,而不是视图的
\uuuu init\uuu
方法

class ExtraCreditForm(forms.ModelForm):

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

        self.fields['recipient'].queryset = ExtraCredit.objects.exclude(recipient=user)
        self.fields['description'].help_text = "Why does this user deserve extra credit?"
然后从视图中删除
\uuuu init\uuu
方法,并设置
form\u class
,使其使用您的模型表单。您已经更新了
get\u form\u kwargs
以将用户传递到表单的
\uuuu init\uuu
方法,因此不必进行任何其他更改。您的
表单\u invalid
方法没有执行任何特殊操作,因此您可以将其删除

class ExtraCreditCreateView(CreateView):
    form_class = ExtraCreditForm
    ...

如果不定义ModelForm,则无法执行此操作。您的视图不是表单,重写其init方法或尝试访问
self.fields
都没有意义。如果不定义ModelForm,您就不能这样做。您的视图不是表单,重写其init方法或尝试访问
self.fields
,都没有意义。谢谢!你把我引向正确的方向。我将在上面发布我的最终解决方案作为更新,但主要更改如下:
self.fields['recipient'].queryset=self.fields['recipient'].queryset.exclude(user\u id=user.id)
以排除当前用户。谢谢!你把我引向正确的方向。我在上面以更新的形式发布我的最终解决方案,但主要更改如下:
self.fields['recipient'].queryset=self.fields['recipient'].queryset.exclude(user\u id=user.id)
以排除当前用户。