Django – Redirect Unauthenticated User trying to access UpdateView to DetailView

Question:

This is my last brain cell speaking.
I have a model called Post with title, body, author, logo and pub_date fields.
There is a page in my app that the user can Update/Edit the post. I want the user to be redirected to the Post’s Detail page if they tried to access it without being logged in.
The problem is that I can’t reference the Post’s pk to redirect the user to the related page, If I want to put it simply:
the user trying to access .../2/edit/ will be redirected to .../2/ if they aren’t logged in

I Tried using LoginRequiredMixin to block the user but I can’t redirect the user to the relative details page.

urls.py:

urlpatterns = [
    path('', PostListView.as_view(), name='index'),
    path('<int:pk>/', PostDetailView.as_view(), name='details'),
    path('new/', PostCreateView.as_view(), name='new_post'),
    path('<int:pk>/edit', PostUpdateView.as_view(), name='update_post'),
]

views.py:

class PostUpdateView(LoginRequiredMixin, UpdateView):
    model = Post
    login_url = reverse_lazy('details', args=[self.object.pk,]) 
    form_class = PostUpdateForm
    template_name = "posts/update_post.html"

I also tried:

class PostUpdateView(LoginRequiredMixin, UpdateView):
    def get_login_url(self) -> str:
        super().get_login_url()
        UpdateView.get(self, self.request)
        self.login_url = reverse_lazy('details', args=[self.object.pk,])
    model = Post
    form_class = PostUpdateForm
    template_name = "posts/update_post.html"

But it returns an empty/none value

Is LoginRequiredMixin even the right way to do this?
I know this can easily be achieved without GenericViews/UpdateView just by getting the request and handling it ourselves, But isn’t GenericViews supposted to get the job done easier?

Asked By: X_ShaygaN_D

||

Answers:

I don’t know what is the name of user field in your Post model. I supposed it as author.

class PostUpdateView(LoginRequiredMixin, UpdateView):
    model = Post
    login_url = reverse_lazy('details', args=[self.object.pk,]) 
    form_class = PostUpdateForm
    template_name = "posts/update_post.html"

    def dispatch(self, request, *args, **kwargs):
        obj = self.get_object()
        if request.user.is_authenticated:
            if obj.author != self.request.user:
                return redirect(obj)
            return super(UpdateStory, self).dispatch(request, *args, **kwargs)
        else:
            return redirect(obj)


    def get_success_url(self, **kwargs):         
        if  kwargs != None:
            return reverse_lazy('details', kwargs = {'pk': kwargs['idnumber']})
        else:
            return reverse_lazy('details', args = (self.object.id,))
Answered By: enes islam
class PostUpdateView(LoginRequiredMixin, UpdateView):
    model = Post
    form_class = PostUpdateForm
    template_name = "posts/update_post.html"
    redirect_field_name = None
    def get_login_url(self) -> str:
         object = self.get_object()
         return reverse_lazy('details', args=[object.pk,])

U need return URL

Answered By: kjaw

Have you tried including

from django.contrib.auth.decorators import login_required

and then just placing this decorator above your class:

@login_required 

so its something like this


@login_required 
class PostUpdateView(UpdateView):
    model = Post
    login_url = reverse_lazy('details', args=[self.object.pk,]) 
    form_class = PostUpdateForm
    template_name = "posts/update_post.html"

Answered By: Lirian