Note: I am new to django
I have been trying to build an application similar to blog posts.
I am using the allauth for social login and auth_views.LoginView.as_view
for custom login.
When someone creates an account, their email is not verified and I used the @verified_email_required
decorator in function based views.
Now when I am using class based views, I want the user to be verified to add or update posts..
Below is my code in 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
When the user is not verified. I get the email as per the send_email_confirmation
function, but I am not redirected to the log-detail page.. I am still able to update the post without verification.
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
function is provided by allauth.
edit:
the solution given worked.. But it raised a new error:
AttributeError at /new-question Generic detail view LogCreateView must be called with either an object pk or a slug in the URLconf.
The add-question class
class LogCreateView(LoginRequiredMixin, VerificationRequiredMixin, CreateView):
model = Log
fields = ['title', 'content', 'image']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
The test_func
is only supposed to return whether the user passes the test or not. But you return a redirect
(which returns a HttpResponseRedirect
) the value of which is truthy and it is considered that your user passed the test. Instead you should simply write a mixin of your own to do this:
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, *args, **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, VerificationRequiredMixin, CreateView):
model = Log
fields = ['title', 'content', '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')