Django 不重定向以进行电子邮件验证

问题描述

注意:我是 Django 的新手
我一直在尝试构建一个类似于博客文章的应用程序。 我使用 allauth 进行社交登录,使用 auth_views.LoginView.as_view 进行自定义登录

当有人创建帐户时,他们的电子邮件未经过验证,我在基于函数的视图中使用了 @verified_email_required 装饰器。

现在,当我使用基于类的视图时,我希望验证用户添加或更新帖子..

下面是我在views.py中的代码

class LogUpdateView(LoginrequiredMixin,UserPassesTestMixin,UpdateView):
    model = Log
    fields = ['title','content','image']
    slug_url_kwarg = 'question'
    slug_field = 'slug'
    
    def form_valid(self,form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            if EmailAddress.objects.get(user=self.request.user).verified == True:
                return True
            else:
                print('Not verified')
                send_email_confirmation(self.request,self.request.user)
                return redirect('log-detail',question=post.slug)
        else:
            return False

用户未通过验证时。我根据 send_email_confirmation 函数收到了电子邮件,但我没有被重定向到日志详细信息页面。我仍然可以在未经验证的情况下更新帖子。

urls.py:

from django.urls import path
from .views import LogListView,LogDetailView,LogCreateView,LogUpdateView,SolutionDetailView,SolutionsCreateView

urlpatterns = [
    path('',LogListView.as_view(),name='home'),path('new-question',LogCreateView.as_view(),name='log-create'),path('question/<slug:question>',LogDetailView.as_view(),name='log-detail'),path('question/update/<slug:question>',LogUpdateView.as_view(),name='log-update'),path('add-solution/<slug:question>',SolutionsCreateView.as_view(),name='log-solution-create'),path('solution/<slug:solution>',SolutionDetailView.as_view(),name='log-solution'),]

send_email_confirmation 函数由 allauth 提供。

编辑:

给出的解决方案有效.. 但它引发了一个新的错误

AttributeError at /new-question Generic detail view LogCreateView must be called with either an object pk or a slug in the URLconf.

添加问题类

class LogCreateView(LoginrequiredMixin,VerificationrequiredMixin,CreateView):
    model = Log
    fields = ['title','image']
    
    def form_valid(self,form):
        form.instance.author = self.request.user
        return super().form_valid(form)

解决方法

test_func 只应该返回用户是否通过测试。但是您返回一个 redirect(返回一个 HttpResponseRedirect),其值真实,并且您的用户通过了测试。相反,您应该简单地编写自己的 mixin 来执行此操作:

from django.core.exceptions import PermissionDenied


class VerificationRequiredMixin:
    def get_verification_redirect(self):
        raise NotImplementedError(
            '{} is missing the implementation of the get_verification_redirect() method.'.format(self.__class__.__name__)
        )
    
    def dispatch(self,request,*args,**kwargs):
        if EmailAddress.objects.get(user=self.request.user).verified:
            return super().dispatch(request,**kwargs)
        print('Not verified')
        send_email_confirmation(self.request,self.request.user)
        return self.get_verification_redirect()


class LogUpdateView(LoginRequiredMixin,UserPassesTestMixin,VerificationRequiredMixin,UpdateView):
    model = Log
    fields = ['title','content','image']
    slug_url_kwarg = 'question'
    slug_field = 'slug'
    
    def form_valid(self,form):
        form.instance.author = self.request.user
        return super().form_valid(form)
    
    def test_func(self):
        post = self.get_object()
        return self.request.user == post.author
    
    def get_verification_redirect(self):
        post = self.get_object()
        return redirect('log-detail',question=post.slug)


class LogCreateView(LoginRequiredMixin,CreateView):
    model = Log
    fields = ['title','image']
    
    def form_valid(self,form):
        form.instance.author = self.request.user
        return super().form_valid(form)
    
    def get_verification_redirect(self):
        return redirect('some_view')