【问题标题】:Django - The view accounts.decorators.wrapper_function didn't return an HttpResponse object. It returned None insteadDjango - 视图 accounts.decorators.wrapper_function 没有返回 HttpResponse 对象。它返回 None 而不是
【发布时间】:2020-07-19 07:11:20
【问题描述】:

我正在构建一个客户管理应用程序并且构建了几个装饰器。但是当我运行应用程序时会出现此错误

视图 accounts.decorators.wrapper_function 没有返回 HttpResponse 对象。它返回 None 。

装饰器.py

from django.http import HttpResponse
from django.shortcuts import redirect


def unauthenticated_user(view_func):
    def wrapper_func(request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect('home')
        elif request.user.is_authenticated == None:
            return redirect('login')
        else:
            return view_func(request, *args, **kwargs)

    return wrapper_func


def allowed_users(allowed_roles=[]):
    def decorator(view_func):
        def wrapper_func(request, *args, **kwargs):

            group = None
            if request.user.groups.exists():
                group = request.user.groups.all()[0].name

            if group in allowed_roles:
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse('You are not authorized to view this page')
        return wrapper_func
    return decorator


def admin_only(view_func):
    def wrapper_function(request, *args, **kwargs):
        group = None
        if request.user.groups.exists():
            group = request.user.groups.all()[0].name

        if group == 'customer':
            return redirect('user-page')

        if group == 'admin':
            return view_func(request, *args, **kwargs)

    return wrapper_function

还有我的观点.py

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.forms import inlineformset_factory
from django.contrib.auth.forms import UserCreationForm

from django.contrib.auth import authenticate, login, logout

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group

from .models import *
from .forms import OrderForm, CreateUserForm, CustomerForm
from .filters import OrderFilter
from .decorators import unauthenticated_user, allowed_users, admin_only

# Create your views here.
@unauthenticated_user
def registerPage(request):
    form = CreateUserForm()
    if request.method == 'POST':
        form = CreateUserForm(request.POST)
        if form.is_valid():
            user =form.save()
            username = form.cleaned_data.get('username')


            messages.success(request,'Account was created for '+ username)
            return redirect('login')

    context = {'form':form}
    return render(request,'accounts/register.html',context)

@unauthenticated_user
def loginPage(request):
    if request.method == 'POST':
        username=request.POST.get('username')
        password=request.POST.get('password')
        user = authenticate(request,username=username, password=password)
        if user is not None:
            login(request,user)
            return redirect('home')
        else:
            messages.info(request, 'Username or password or incorrect')
    context = {}
    return render(request,'accounts/login.html',context)


def logoutUser(request):
    logout(request)
    return redirect('login')

@admin_only
@login_required(login_url='login')
def home(request):
    orders = Order.objects.all()
    customers = Customer.objects.all()

    total_customer = customers.count()
    total_orders = orders.count()
    delivered = orders.filter(status='Delivered').count()
    pending  = orders.filter(status='Pending').count()


    context = {'orders':orders,'customers':customers,'total_orders':total_orders,'delivered':delivered,'pending':pending}
    return render(request, 'accounts/dashboard.html',context)

@login_required(login_url='login')
@allowed_users(allowed_roles=['customer'])
def userPage(request):
    orders = request.user.customer.order_set.all()

    total_orders = orders.count()
    delivered = orders.filter(status='Delivered').count()
    pending  = orders.filter(status='Pending').count()

    context = {'orders':orders,'total_orders':total_orders,'delivered':delivered,'pending':pending}
    return render(request, 'accounts/user.html',context)

@login_required(login_url='login')
@allowed_users(allowed_roles=['customer'])
def accountSettings(request):
    customer = request.user.customer
    form = CustomerForm(instance=customer)

    if request.method == 'POST':
        form = CustomerForm(request.POST, request.FILES,instance=customer)
        if form.is_valid():
            form.save()


    context = {'form':form}
    return render(request, 'accounts/account_settings.html', context)

@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def product(request):
    products = Product.objects.all()
    return render(request, 'accounts/products.html', {'products': products})

@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def customer(request,pk_test):
    customer = Customer.objects.get(id=pk_test)

    orders = customer.order_set.all()
    order_count = orders.count()
    myFilter = OrderFilter(request.GET, queryset=orders)
    orders = myFilter.qs
    context = {'customer':customer,'orders':orders,'order_count':order_count,'myFilter':myFilter}

    return render(request, 'accounts/customer.html',context)

@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def createOrder(request,pk):
    OrderFormSet = inlineformset_factory(Customer,Order, fields=('product', 'status'),extra=10)
    customer = Customer.objects.get(id=pk)
    #form = OrderForm(initial={'customer':customer})
    formset = OrderFormSet(queryset=Order.objects.none(),instance=customer)
    if request.method == 'POST':
        #print('Printing POST',request.POST)
        #form = OrderForm(request.POST)
        formset = OrderFormSet(request.POST,instance=customer)
        if formset.is_valid():
            formset.save()
            return redirect('/')



    context = {'formset':formset}
    return render(request,'accounts/order_form.html',context)


@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def updateOrder(request,pk):
    order = Order.objects.get(id=pk)
    form = OrderForm(instance=order)
    context = {'form':form}
    if request.method == 'POST':
        #print('Printing POST',request.POST)
        form = OrderForm(request.POST,instance=order)
        if form.is_valid():
            form.save()
            return redirect('/')
    return render(request,'accounts/order_form.html',context)


@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def deleteOrder(request,pk):
    order = Order.objects.get(id=pk)
    if request.method == 'POST':
        order.delete()
        return redirect('/')
    context={'item':order}
    return render(request, 'accounts/delete.html',context)

Output when i run my local server

这是我的第一个问题,如果我没有提供任何有用的信息来回答这个问题,请告诉我

【问题讨论】:

  • 如果条件不满足,admin_only 中的包装函数不返回响应。你需要退货

标签: django django-models django-views python-decorators


【解决方案1】:

我有同样的错误,我是怎么解决的?实际上这是一个愚蠢的错误。 首先。 转到管理员,转到用户而不是组部分,您会看到您没有为该客户分配任何组。根据您的选择分配客户组或管理员组。

这是我的错误,我没有分配任何组。我希望你也犯了同样的错误。

【讨论】:

  • 谢谢!它有助于。冰雹丹尼斯常春藤 :)
【解决方案2】:

正如 Lain Shelvington 在 cmets 中提到的,您的 admin_only 装饰器不会为“管理员”和“客户”以外的组返回响应:

def admin_only(view_func):
    def wrapper_function(request, *args, **kwargs):
        group = None
        if request.user.groups.exists():
            group = request.user.groups.all()[0].name

        if group == 'customer':
            return redirect('user-page')
        elif group == 'admin':
            return view_func(request, *args, **kwargs)
        else:
            return # <- return response here (possibly a redirect to login page?)

    return wrapper_function

【讨论】:

    【解决方案3】:

    希夫,

    如果您按照 Dennis Ivy 的教程进行操作,但仍然遇到此问题,请尝试以下操作:

    1. 使用超级用户帐户登录 Django 管理站点
    2. 返回主站点
    3. 注销并尝试创建另一个用户

    我在处理信号视频时遇到了同样的错误。我不确定是否还有需要修复的错误,但这让该应用再次为我工作。

    【讨论】:

      【解决方案4】:

      希夫,

      我假设您正在关注 youtube 上 Dennis Ivy 的教程...

      我遇到了完全相同的问题。而对我来说,这是因为当我第一次将我的数据库从 sqlite 迁移到 PostgreSQL,然后从 PostgreSQL 迁移到 AWS RDS 时,不知何故我所有的用户信息都丢失了。

      我的解决方法是创建一个新的超级用户(因为我的被删除了): python manage.py createsuperuser 然后使用这个新的超级用户登录信息,登录到管理面板。您将看到您的超级用户分配到任何组,如果您检查您的组面板,您会看到我们之前创建的组变量,即customeradmin这里。所以继续创建这两个组类型。然后返回“用户”面板并为您的超级用户分配 admin 变量。

      然后注销并转到您的/register/ 页面并创建一个普通帐户(不是管理员,只是一个客户)。然后,如果您登录超级用户帐户并再次进入管理面板,您将看到为您的普通用户(客户)分配了 customer 变量就好了。

      这就是我解决问题的方法。我希望它对你有帮助。干杯。

      【讨论】:

      • 有同样的错误。感谢您的详细说明。冰雹丹尼斯常春藤 :)
      • 嗨,我也做了同样的事情,但是在我注册一个普通用户并点击配置文件后,这个错误来了:“ValueError at /profile/ 未设置必需的参数名称”。
      【解决方案5】:

      对于某些会收到此错误的人,用户“sogu”的响应在我的情况下修复了它: SQLite works, but PostgreSQL migrated database causes ERROR - Django 3.0 (如果其他解决方案不适合您,请查看那个)

      【讨论】:

        【解决方案6】:

        问题是您登录的帐户不属于任何组。我假设这是您第一次创建的管理员帐户。转到管理页面->然后转到用户->并将管理组分配给他。但是那里给出了一个更好的答案,因为它确实提供了修复。

        【讨论】:

          【解决方案7】:

          添加此代码以自动为新用户分配他所属的组。

          @unauthenticated_user
          def registerPage(request):
          
              form = CreateUserForm()
              if request.method == 'POST':
                  form = CreateUserForm(request.POST)
                  if form.is_valid():
                      user = form.save()
                      username = form.cleaned_data.get('username')
          
                      group = Group.objects.get(name='customer')
                      user.groups.add(group)
          
                      messages.success(request, 'Account was created for ' + username)
          
                      return redirect('login')
                  
          
              context = {'form':form}
              return render(request, 'accounts/register.html', context)
          

          【讨论】:

            猜你喜欢
            • 2017-01-25
            • 2018-09-14
            • 1970-01-01
            • 2015-06-26
            • 1970-01-01
            • 2017-12-28
            • 1970-01-01
            相关资源
            最近更新 更多