python - Login_Required Django 不使用 FormView

标签 python django authentication decorator formview

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

'QueryDict' object has no attribute 'user'

我如何编写此 View /表单以使其按照我描述的方式运行?

查看:

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_valid 方法中重新实例化 form 很奇怪,该方法接收绑定(bind)表单作为参数。

您从表单的自定义保存方法返回 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/

相关文章:

python - 资源暂时不可用 : mod_wsgi (pid=28433): Unable to connect to WSGI daemon process

python - Django:使用 mod_wsgi 创建的 SOCK 文件的权限错误

c# - mvc 5 检查用户角色

c++ - 在 C++ 中对 facebook 进行身份验证

python - 对 pandas 系列中的日期数据进行排序

python - 在列表字典上实现过滤器的最有效方法

python - 使用 python 正则表达式的词标记化

python - 使用 django 和自定义脚本的 HTML 表单操作

python - AWS Cognito 作为网站的 Django 身份验证后端

python - 如何使用 python 更改嵌套作用域中的全局变量?