我有一个FormView,基本上是一个产品页面。您可以查看产品详细信息并通过该页面上的表单请求产品。我希望设置该页面,以便任何人都可以查看该页面,但是只有登录的用户才能请求该产品。为此,我向FormView中的post函数添加了一个login_required装饰器,但出现错误:


  'QueryDict'对象没有属性'user'


如何编码此视图/表单,使其按我描述的方式工作?

视图:

class RedeemReward(SingleObjectMixin, FormView):
    template_name = 'reward.html'
    slug_field = 'reward_slug'
    form_class = Redeem_Reward
    model = Reward

    @method_decorator(login_required)
    def post(self, request, *args, **kwargs):
        return super(RedeemReward, self).post(request, *args, **kwargs)

    def form_valid(self, form):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        #form = self.get_form(self.get_form_class())
        #form.save(self.request.POST)
        form.save(self.request.POST)
        return super(RedeemReward, self).form_valid(form)

    def get_success_url(self):
        return reverse('reward_confirmation', args=(self.object.reward_slug, self.object.reward_code))

    def dispatch(self, *args, **kwargs):
        self.object = self.get_object()
        return super(RedeemReward, self).dispatch(*args, **kwargs)


形成:

class Redeem_Reward(forms.Form):
    quantity = forms.IntegerField(label=_('Quantity'), error_messages={'invalid':'Must be a valid number'})
    reward_name = forms.CharField(max_length=50, widget=forms.HiddenInput(), label=_('Reward Name'), error_messages={'invalid':'Invalid reward'})
    def clean_quantity(self):
        """
        Validate that the user entered a valid number.
        """
        return self.cleaned_data['quantity']
    def clean_reward_name(self):
        """
        Validate that this reward code exists.
        """
        try:
            existing_reward = Reward.objects.get(reward_name=self.cleaned_data['reward_name'])
        except ObjectDoesNotExist:
            raise forms.ValidationError(_("The reward you requested does not exist."))
        return self.cleaned_data['reward_name']
    def save(self, request, *args, **kwargs):
        """
        Save all of the required data.
        """
        user = request.user
        #user_points = Points.objects.filter(affiliate__id=user.id).annotate(total_points=Sum('points'))
        user_points = Affiliate.objects.filter(points__affiliate__id=user.id).annotate(total_points=Sum('points'))
        user_points = user_points[0].total_points
        error_message = {'lookuperror':'You need to provide a valid quantity',
                         'insufficient_points':"You don't have enough points for this purchase."}
        try:
            quantity = self.cleaned_data['quantity']
            reward_name = self.cleaned_data['reward_name']
            rewards = Reward.objects.get(reward_name=reward_name)
        except LookupError:
            raise Http404
        try:
            points_cost = -(rewards.reward_cost * quantity)
        except ArithmeticError:
            raise Http404
        quote_price = -(points_cost)
        if user_points >= quote_price:
            reward_order = Points.objects.create(affiliate=user, reward=rewards, points=points_cost, from_reward=True, from_offer=False, from_referral=False)
            status_cost = Status_Code.objects.create(short_name="Pending", name="The order is currently being reviewed", description="The order is in queue")
            redeem_order = Redeem.objects.create(affiliate=user, reward=rewards, status_code=status_code)
            redeem_details = Redeem_Details.objects.create(redeem=redeem_order, quantity=quantity, quote_price=quote_price)
            return HttpResponseRedirect(reverse('reward_confirmation', args=(redeem_details.redeem_code,)))
        else:
            return render(request, 'reward.html', {'error_message':error_message['insufficient_points']})

最佳答案

您正在将self.request.POST传递给表单的save方法,该方法设置为将请求作为其第一个参数。或至少具有user属性的内容。如果改用self.request传递,则将不再遇到该特定错误。

奇怪的是,您要在form方法中重新实例化form_valid,该方法接收绑定形式作为参数。

您要从表单的自定义保存方法(非标准)返回HttpResponse对象。但是,只要这样做,就应该从form_valid方法返回它们。

总而言之,是这样的:

def form_valid(self, form):
    return form.save(self.request)

关于python - Login_Required Django无法与FormView一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19733630/

10-12 17:04