Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialCheo R
37,150 PointsDjango Authentication - SignUpView - Challenge Task 2 of 2 . Not sure if I am on the right path.
After visiting the Django auth and CreateView docs and various attempts I still stump. I included FormMixin, needed for from_valid (else it gives task 1 no longer passing, error). Included
login(self.request, form.get_usere())
As shown in a previous video and imported HttpResponseRedirect to redirect after a successful login.
from django.contrib.auth import authenticate, login
from django.views.generic.edit import FormMixin
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseRedirect
from django.views import generic
from . import forms
class SignUp(FormMixin, generic.CreateView):
form_class = forms.UserCreateForm
template_name = 'accounts/signup.html'
success_url = reverse_lazy("products:list")
def get_form(self, form_class=None):
"""
Returns an instance of the form to be used in this view.
"""
if form_class is None:
form_class = self.get_form_class()
return form_class(**self.get_form_kwargs())
def form_valid(self, form):
login(self.request, form.get_user())
return HttpResponseRedirect(self.get_success_url())
3 Answers
Lewis Cowles
74,902 PointsIn this instance, get_user()
would only work for a logged in user of a form (no ID or user object is provided), you are trying to login a user so we don't have that.
I'm quite certain the code challenge is broken in any case, but looking at the docs, it seems we need to return the user via the authenticate method, and then if the user is not None, and they are also active log them in
I'm having problems with the challenge too, but I'm quite sure my code for 2/2 should work Kenneth Love Lacey Williams Henschel please help
def form_valid(self, form):
res = super().form_valid(form)
user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
if user is not None:
if user.is_active:
login(self.request, user)
return res
Lars Wettmann
15,376 PointsI don't get it. I have this - so the same as you guys basically, but "Task 1 is no longer passing"... why are the tips from the testing so unhelpful?? Where's the error?
from django.core.urlresolvers import reverse_lazy
from django.contrib.auth import authenticate
from django.views import generic
from . import forms
class SignUp(generic.CreateView):
form_class = forms.UserCreateForm
template_name = 'accounts/signup.html'
success_url = reverse_lazy('products:list')
def form_valid(self, form):
res = super().form_valid(form)
user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
if user is not None:
if user.is_active:
login(self.request, user)
return res
Kenneth Love
Treehouse Guest TeacherYou'll get the "step 1 is no longer passing" error when a step after the first has a fatal error. It's hard/impossible to catch these errors in our code runner so...I can't give you a better error message or I would.
Your problem here, though, is that you used login
without importing it.
Lars Wettmann
15,376 PointsAh, Kenneth Love ... thanks for clarifying .. and Uff.. so stupid of me. Sorry for bothering you guys.
Kenneth Love
Treehouse Guest TeacherNot stupid at all! We all miss imports from time to time, especially when we can't get that kind of debugger easily.
Kenneth Love
Treehouse Guest TeacherKenneth Love
Treehouse Guest TeacherYou should do the
super()
first.CreateView
doesn't save the record until the defaultform_valid
runs.Lewis Cowles
74,902 PointsLewis Cowles
74,902 Pointslooks like for some weird reason django requires it's password field to be named password1 as well... I feel like a bit of a ******** not seeing that one...
Kenneth Love
Treehouse Guest TeacherKenneth Love
Treehouse Guest TeacherIn the authentication form, yeah, it's named
password1
. Orpassword2
if you wanted to use the confirmation fieldLewis Cowles
74,902 PointsLewis Cowles
74,902 PointsI've submitted a PR to Django on this. If they will have arbitrary field / property names, documenting them in a logical place would probably help https://github.com/django/django/pull/7314
Ryan Oldford
11,992 PointsRyan Oldford
11,992 PointsDid this work in the end? I'm still getting problems with this, and I think I've added everything you're recommending.
Here's my code:
Lewis Cowles
74,902 PointsLewis Cowles
74,902 PointsHey buddy, looks like you are not capturing the default return value, so
super().form_valid(form)
should become
res = super().form_valid(form)
I've only glanced so there may be more needing work, but this is definitely needed.
Explanation
I'm pretty sure it should return the value of super (mine does and I called the value
res
) so that default behavior is preserved.form_valid
is what to do if the form is valid.Hope this helps
Ryan Oldford
11,992 PointsRyan Oldford
11,992 PointsOkay, just after I almost gave up, I changed the smallest thing and it worked. ?
It turns out that you do need to capture the value of super().form_valid(form)...
but you don't need to have the view class extend FormMixin. Removing that from my code turned out to be the key.
Thanks for all your help!