I have a django project with two apps, the first is called 'main', where the user can login and register and all the authentication stuff is made and the other is 'app' where only authenticated users can access.
Main.views:
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
messages.success(request, f"New account created: {username}")
login(request, user)
return redirect("app:app_index")
else:
for msg in form.error_messages:
messages.error(request, f"{msg}: {form.error_messages[msg]}")
return render(request = request,
template_name = "main/register.html",
context={"form":form})
form = UserCreationForm
return render(request = request,
template_name = "main/register.html",
context={"form":form})
All the code works fine and allows me to login, register, logout... but now I need to export that user to the 'app' app in order to use the user data on the app template, how can I migrate the user and all its data?
I wonder I would be able to just do
app.views:
from main.views import user
but definitely this does not work, any suggestion will be much appreciated
Actually you can simply access use information an all your apps with object notation.
In my case, the user object has username attribute, so when I want to use the users' username I can simply type
user.username
And it will return the username saved on the database for the specific user that's loged in
Related
I am fairly new to Django so I wanted to know what should I do to make default authenticate function of Django accepts only email and password to login, assuming that in sign-up form I have both username and email. The following code does not work properly.However when I add
username = request.POST.get('username')
and change
user = authenticate(request, username=username email=email, password=password)
It logs in as expected.
The login View:
def LoginPage(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
print('logged')
return redirect('/inker/')
return render(request, 'authy/login.html')
The sign up view:
def SignUpPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
return redirect('/login/')
context={'form':form}
return render(request, 'authy/signup.html', context)
The form module:
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email', 'password1', 'password2']
As you can see in Sign Up view we have both username and email but in login form I want it to just login user based on only email. How can I implement this.
Also how can I compact both username and email into one input when user wants to login? pretty much like instagram, facebook login page
If you just want to access user using email, you're not using authentication on the first place. So, to solve your purpose, following approaches can be followed:
Get user email in url params in every request (so that user can be identified)
Set default password while creating the user account for all users and use that password while authentication (not recommended)
ValueError at /register/
The given username must be set
Request Method: POST
Request URL: http://127.0.0.1:8000/register/
Django Version: 1.11.4
Exception Type: ValueError
Exception Value:
The given username must be set
here's the views.py
def register_page(request):
form = RegisterForm(request.POST or None)
context = {
"form": form
}
if form.is_valid():
print(form.cleaned_data)
username = form.cleaned_data.get("username")
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
user = User.objects.create_user(username,email,password)
print(username)
return render(request, "auth/register.html", context)
This is sending None as a username and i dont know why?
user = User.objects.create_user(username,email,password)
How to resolve this issue? It is not getting the username with POST method or there is some other mistake?
First, you are doing lots of things even though you are not in the POST case.
I suggest you check whether you are in POST or not.
if request.method == 'POST':
If you are in POST, you can retrieve the form with :
form = RegisterForm(request.POST)
if you are not in POST, you must send an empty form to the page with :
form = RegisterForm()
Then, after having checked that the form is valid, you can already create your new user.
user = User()
Note that you must import the class User with : from django.contrib.auth.models import User
Now you can retrieve the data from your form as you did, and assign it to your new empty User:
user.username = form.cleaned_data.get('username')
user.email = form.cleaned_data.get('email')
For the password, you should encrypt it with :
user.password = make_password(form.cleaned_data.get('password'))
Note that you must import the make_password method : from django.contrib.auth.hashers import make_password
After all this, you can save your new user to the database :
user.save()
Note that you should probably do the save into a try: ... except block in order to catch potential exception caused by IntegrityError if several users try to register with the same username or such, depending on the Integrity rules that Django uses for his User model by default (which I don't remember)
Finally, your view should look like that (or similar) :
def register_page(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
user = User()
user.username = form.cleaned_data.get('username')
user.email = form.cleaned_data.get('email')
user.password = make_password(form.cleaned_data.get('password'))
user.save()
else:
form = RegisterForm()
return render(request, 'auth/register.html', {'form': form})
It should work considering you made your imports, a proper RegisterForm, and a proper auth/register.html
I am creating a simple web app. The user suppose to signup and can see their profile. The signup form is working fine and the user can signup perfectly.
In the forms.py I have function to raise validation error when the user signup with an existing username. Here is the problem. If there is an username types for example - 'userone' , and another user types 'user.one' it saves the new user with 'user.one'. But when the user wants to go to their profile, the problem arises in the URL. Because I am using username as slug, the dot(.) is not present in the URL which leads to the problem.
I have tried with re_path as mentioned in the Django document, but still getting errors.
forms.py to check unique username
def clean_username(self):
username = self.cleaned_data.get('username')
email = self.cleaned_data.get('email')
if username and User.objects.filter(username=username).exclude(email=email).count():
raise forms.ValidationError('This username already exists')
return username
views.py (signup class)
class SignupView(View):
form_class = SignupForm
template_name = 'webapp/user_signup.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form':form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('webapp:home')
views.py (for profile class)
class ProfileView(generic.DetailView):
model = User
slug_field = 'username'
template_name = 'webapp/user_profile.html'
urls.py
urlpatterns = [
# user signup link
path('user/signup/', views.SignupView.as_view(), name='signup'),
. . . .. . . .. . . ..
# user profile view
path('user/<slug:slug>/', views.ProfileView.as_view(), name='user_profile'),
]
HTML
{{article.user.first_name}} {{article.user.last_name}}
What should be a perfect approach for this?
The only problem here is that your URL pattern doesn't accept dots. You could change it to a str, which accepts anything:
path('user/<str:slug>/',
Or use a regex if you want to be a bit more selective about what you accept:
re_path(r'user/(?P<slug>[\w.]+)/$',
I've been trying to use Django's authentication system to login in a user. But I can't figure out how to create a User object, I've just been playing around with it so far:
def sign_in(request):
form = NameForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
username = request.POST.get(post.question_text)
password = request.POST.get(post.id_text)
user = authenticate(username=username, password=password)
if user is not None:
login(request,user)
return HttpResponse('hi')
else:
return HttpResponse('bye')
else:
form = NameForm()
return render(request, 'checkin/sign_in_new.html', {'form': form})
The program keeps returning bye. I'm not sure what I need to put as the parameters for request.POST.get(), the Django docs uses 'username' and 'password' respectively. Do I need to write code to create the user first? I created one in the Django API
The user doesn't exist. Go to admin and create one first. And yes user needs to be created before you attempt to sign in.
Okay I figured it out, I just need to create the user in my code first. I just added user = User.objects.create_user('charlie', 'charlesdsmith25#gmail.com', 'smith') so now it's:
def sign_in(request):
#we need to handle all the data that was just typed, we'll add a condition for that
form = NameForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
username = request.POST.get('username')
password = request.POST.get('password')
user = User.objects.create_user('charlie', 'charlesdsmith25#gmail.com', 'smith')
auth = authenticate(username=username, password=password)
if user is not None:
login(request,user)
return HttpResponse('hi')
else:
return HttpResponse('bye')
else:
form = NameForm()
return render(request, 'checkin/sign_in_new.html', {'form': form})
I am trying to create a portable auth system that can be plugged in apps, and each different app I reimplement it in has the same issues.
1-Sometimes the user that recently logged in gets their sn in the email address field when a new user tries to register, as below
2- Sometimes a new user registers and logs out but the form will put the old user's email address and password in the appropriate fields, when of course I want the form to be blank if the user has logged out
3- always the last password used is filled in upon reload
I just want the form to completely clear itself when reloaded
How to clear form fields after a submit in Django
I have tried all 3 solutions from a similar question, I reinstantiated the from after saving the valid one, made a copy of request.POST and used that instead, and I was already redirecting to begin with. Here is my form
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
in views.py
def register(request):
context = RequestContext(request)
registered = False
user_form = UserForm()
if request.method == 'POST':
pDict = request.POST.copy()
form = UserForm(pDict)
if form.is_valid():
user = form.save()
user.set_password(user.password)
user.save()
user_form = UserForm()
registered = True
username = pDict['username']
password = pDict['password']
user = authenticate(username=username, password=password)
login(request, user)
#locals isn't working? won't print user
return HttpResponseRedirect('/url/')
else:
print user_form.errors
template_name = 'accounts/register.html'
user_form = UserForm()
response = TemplateResponse(request, 'accounts/register.html', locals())
return response
thank you