I have an app in django 1.11. Below is the view with the form where the user can sign up for the event, after saving he gets a message about the details - on the same page, at the same url. But, after saving the form is completed and after pressing F5 the next saving is performed. How can I avoid this?
I think something with the form_valid method is wrong.
class EventDetailView(DetailView, CreateView):
model = models.Event
form_class = forms.ParticipantForm
context_object_name = 'event'
template_name = 'events/event_detail.html'
def get_success_url(self):
return reverse('events:detail', kwargs={'slug': self.kwargs['slug'], 'pk': self.kwargs['pk']})
def form_valid(self, form):
self.object = form.save()
context = self.get_context_data()
context['registered_event'] = context['event']
return self.render_to_response(context)
After a successful form submission, you should redirect to prevent duplicate submissions.
def form_valid(self, form):
self.object = form.save()
return redirect(self.get_success_url())
Remember to add the import
from django.shortcuts import redirect
use flash message to show messages.
from django.contrib import messages as flash_messages
flash_messages.success(request, "Your Message Here")
and refresh page.
Related
I am using Django class-based views for my project and trying to redirect user from registration view if he is already authenticated. I've done it already with LoginView and it was pretty simple and looked just like adding few lines of code:
class Login(LoginView):
authentication_form = CustomAuthenticationForm
redirect_authenticated_user = True
LOGIN_REDIRECT_URL = "core:profile"
So after going to url for login, user ends up at his profile url. Absolutely simple and works perfectly.
However, there is no CBV for registration and therefore CreateView should be used, which doesn`t have any attributes for checking if user is authenticated.
The one method of doing something similar is UserPassesTestMixin, but it only gives me 403 Forbidden if user is authenticated, not redirect.
Here is my current registration view:
class Registration(UserPassesTestMixin, CreateView):
form_class = RegistrationForm
template_name = "registration/user_form.html"
success_url = reverse_lazy("core:profile")
def test_func(self):
return self.request.user.is_anonymous
def form_valid(self, form):
print(self.kwargs)
self.object = form.save(commit=True)
self.object.is_active = True
self.object.save()
login(self.request, self.object, backend="core.auth_backend.AuthBackend")
return HttpResponseRedirect(self.success_url)
Maybe somebody have done it already?
Would be very grateful for every advice!
In your Registration class, add a get method and remove your test_func:
def get(self,request,*args,**kwargs):
if self.request.user.is_authenticated:
return HttpResponseRedirect('redirect_url')
return super().get(request,*args,**kwargs)
I am a bit confused on why my LoginView message is not pulling the users login name. I have tried a few different ways and it either will say 'Welcome Anonymous User' or 'Welcome' (not adding anything). I have tried a few different methods and the results are the same each way I try to solve it. My code is as follows:
class MyLoginView(LoginView):
template_name = 'registration/login.html'
success_message = 'Welcome'
def form_valid(self, form):
"""Add message here"""
messages.add_message(self.request, messages.INFO, f"{self.success_message} {self.request.user}")
return super().form_valid(form)
This one will say 'Welcome AnonymousUser', if I change the code to {self.request.user.username} it just will say 'Welcome'
also have tried
class MyLoginView(LoginView):
template_name = 'registration/login.html'
def form_valid(self, form):
messages.success(self.request, f'Welcome {self.request.user}')
return super().form_valid(form)
This one will flash the message of 'Welcome Anonymous User'. If I change the code to f'Welcome {self.request.user.username}' then the message displayed is just 'Welcome'
I am not really sure why these aren't working so any help would be greatly appreciated
The problem is your user isn't logged in yet when you write that line. The user is logged in to the request after you have called super().form_valid(form). What you can do to get the user object is to call form.get_user():
class MyLoginView(LoginView):
template_name = 'registration/login.html'
def form_valid(self, form):
user = form.get_user()
messages.success(self.request, f'Welcome {user}')
return super().form_valid(form)
Perhaps a simple way to solve this is to swap the super() call and sending the message:
class MyLoginView(LoginView):
template_name = 'registration/login.html'
def form_valid(self, form):
response = super().form_valid(form)
messages.success(self.request, f'Welcome {self.request.user}')
return response
The response of a successful POST request with form_valid is a redirect, so that means that we do not need to render the message in the response here. It will make a redirect, and the redirect URL will then render the message.
I have the following custom DeleteView:
class CarDeleteView(LoginRequiredMixin, DeleteView):
model = Car
context_object_name = 'car'
template_name = 'cars/car_confirm_delete.html'
success_message = "%(name)s is pending removal"
def get_success_url(self):
return reverse('car-list')
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
name = self.object.name
owner = self.object.owner
if owner != self.request.user:
messages.error(request, f'You don\'t have permissions to remove {name}')
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
# DO Stuff
return redirect(reverse('car-list'))
I'm trying to redirect to previous entry point when user isn't the owner (so he can't delete). But HttpResponseRedirect(request.META.get('HTTP_REFERER')) gives me the URL of the current page (car_confirm_delete.html) and not the previous one. How can I make it go to previous one? Maybe that's because Django does POST?
You need to import HttpResponseRedirect
from django.http import HttpResponseRedirect
and then
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Once the user has made a valid post and pressed Post, I want them to be taken to the valid post. I ran a test with return redirect('post-detail', 18). At the moment once a valid post had been made then the post with ID 18 is loaded.
I am trying to get the ID of the newly created post. What I am trying to write is return redirect('post-detail', id of newly created post)
As this line works form.instance.author = self.request.user, I tried form.instance.id
but it didn't have the desired results.
Does anyone have any suggestions?
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return redirect('post-detail', 18)
#print (form.instance.id)
return redirect('post-detail', form.instance.id)
You did not save the form, hence that means that at that point in time the object has no primary key yet. Normally the form is saved in the basic form_valid method.
You furthermore probably better override get_success_url, since that is the place where you are supposed to "calculate" the url to redirect to:
from django.urls import reverse
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def get_success_url(self):
return reverse('post-detail', args=[self.object.pk])
def form_valid(self, form):
form.instance.author = self.request.user
# will save the form and redirect to the success_url
return super().form_valid(form)
I have a Django blog where the users can set the status of each post (active, inactive) when creating them. I am using Django's generic class-based views and would like to redirect the user to their created post only when the status is set to "active", otherwise they should be redirected to the homepage. How can I retrieve this submitted info from the form to create an if statement? For example: if status == "a"...
views.py
from .models import Listing
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic import CreateView
class PostCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Post
fields = ['title', 'status', 'content']
template_name = 'blog/post-form.html'
success_message = 'Your post has been created.'
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
I think "redirect" is not valid withing the method (form_valid) so you should definitely put something like def post, and get the value in request.data. I'm going to try showing you a code that is working for me in production. You let me know if it was the right response.
class LoginFormView(FormInvalidMessageMixin, LoginView):
template_name = "clientes/login.html
def post(self, request, *args, **kwargs):
username = self.request.POST.get('username')
password = self.request.POST.get('password')
tipo_cuenta = self.request.POST.get('tipo-cuenta')
tipo_cuenta = tipo_cuenta.strip()
user = authenticate(username=username, password=password)
if user:
if has_group(user, 'admin'):
messages.success(request, _('Not for admin'))
return redirect('/login')
cliente = Usuario.objects.filter(usuario=user).first()
sucursal = Sucursal.objects.filter(usuario=user).first()
empleado = Empleado.objects.filter(usuario=user).first()
if tipo_cuenta == 'Punto afiliado':
login(self.request, user)
return redirect('/envios')