Django 装饰器。需要帮助以找到基于类的视图的解决方案

Posted

技术标签:

【中文标题】Django 装饰器。需要帮助以找到基于类的视图的解决方案【英文标题】:Django decorators . Need help to find a solution for class based views 【发布时间】:2021-05-11 08:00:42 【问题描述】:

这是我正在处理的文件。如何限制用户访问此页面? 我只希望管理员访问此页面。我尝试使用自定义装饰器,但它显示基于类的视图错误。我是初学者,所以有人可以帮忙吗??

views.py

class student_register(CreateView):
     model = User
     form_class = StudentSignUpForm
     template_name = 'registration/student_register.html'


   def form_valid(self, form_class):
       user = form_class.save()
     # login(self.request, user)
       return redirect('datapage')

forms.py

class StudentSignUpForm(UserCreationForm):
     first_name = forms.CharField(required=True)
     last_name = forms.CharField(required=True)
     phone_number = forms.CharField(required=True)
     semester = forms.CharField(required=True)
     email = forms.EmailField(required=True)

     class Meta(UserCreationForm.Meta):
          model = User
    

     @transaction.atomic
     def save(self):
         user = super().save(commit=False)
         user.is_student = True
         user.first_name = self.cleaned_data.get('first_name')
         user.last_name = self.cleaned_data.get('last_name')
         user.email = self.cleaned_data.get('email')
         user.username = self.cleaned_data.get('username')
         user.password1 = self.cleaned_data.get('password1')
         user.password2 = self.cleaned_data.get('password2')
         user.save()
         student = Student.objects.create(user=user)
         student.phone_number=self.cleaned_data.get('phone_number')
         student.semester=self.cleaned_data.get('semester')
         student.save()
         return user

urls.py

urlpatterns = [
          path("loginrequest/", views.login_request, name="login"),
          path("logoutrequest", views.logout_request, name="logout"),
          path('student_register/', student_register.as_view(), name='student_register'),
          path('teacher_register/',views.teacher_register.as_view(), name='teacher_register'),
         ]

student_register.html

<div class="container my-3">
<div class="form-group">
  <h3>Register here!</h3>
  <br>
  <form  method="POST" class="post-form"  enctype="multipart/form-data">
      % csrf_token %
   form.as_p 
   form.media
      <button type="submit" class="btn btn-success">Register</button>
  </form>
</div>

【问题讨论】:

【参考方案1】:

你应该使用 Mixins 而不是 UserPassesTestMixin 应该是合适的

class IsAdmin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_admin

    def handle_no_permission(self):
        return redirect('someview')

class StudentRegister(IsAdmin, CreateView):
    ...

【讨论】:

如果用户不是管理员,我如何重定向?【参考方案2】:

您可以将UserPassesTestMixin 用作

from django.contrib.auth.mixins import UserPassesTestMixin


class StudentRegisterView(UserPassesTestMixin, CreateView):
    model = User
    form_class = StudentSignUpForm
    template_name = 'registration/student_register.html'

    def form_valid(self, form_class):
        user = form_class.save()
        # login(self.request, user)
        return redirect('datapage')

    def test_func(self):
        return self.request.user.is_authenticated and self.request.user.is_superuser

【讨论】:

以上是关于Django 装饰器。需要帮助以找到基于类的视图的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

Django中基于类的视图上带有参数的函数装饰器

django-内置装饰器

如何根据 Django 中当前基于类的通用视图模型向模板加载器添加路径

Django报错:AttributeError: 'function' object has no attribute 'as_view'

基于类的视图django中的JWT验证

Django编写RESTful API:基于类的视图