Issue with django request,get user from bd - django

SO,I want to get user details from database and show them in user.html,but I cant do it. They dont display in this file. I tried to do class UserView(ListView):, but it wasnt working. Maybe I didnt understand request.
view.py
def registerform(request): ##registerform
form = SightUp(request.POST or None)
if form.is_valid():
user_obj = form.save()#Сохранение значений в датабазе методом .save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
email = form.cleaned_data.get('email')
user = authenticate(username=username,password =raw_password,email=email)
login(request,user)
return redirect('/userprofile/')# ЗАМЕНИТЬ
context = {'form':form }
return render(request,'user.html',context)
#def userprofiles(request):
# userall = detailsuser.objects.all()
# context = {
# 'objects':userall
# }
# return render(request,'userprofile.html', context)
class UserView(ListView):
model = User
template_name = 'userprofile.html'
context = 'detailsuser'
def get_queryset(self):
return detailsuser.objects.filter(user = self.request.user)
forms.py
class SightUp(UserCreationForm):
first_name = forms.CharField( widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}), max_length=32, help_text='First name')
last_name = forms.CharField( widget = forms.TextInput(attrs={'class':'form-control','placeholder':'Last name'}), max_length=32)
email = forms.EmailField(widget =forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Email'}), max_length =64,help_text='Enter valid Email')
username = forms.CharField(widget =forms.TextInput(attrs={'class':'form-control','placeholder':'Username'}))
password1 = forms.CharField(widget =forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password1'}))
password2 = forms.CharField(widget =forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password2'}))
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('first_name','last_name','email')
user.html
{% for i in detailsuser %}
<h1> yourname: i.email </h1>
{% endfor %}
<h1>Your last name:</h1>
<h1>Your nickname:</h1>
models.py
class detailsuser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)

Your challenge stems from the register view you need to make a conditional test for the POST method like so:
def registerform(request): ##registerform
if request.method == 'POST': #Here is where you make the condition for POST
form = SightUp(request.POST or None)
if form.is_valid():
user_obj = form.save()#Сохранение значений в датабазе методом .save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
email = form.cleaned_data.get('email')
user = authenticate(username=username,password =raw_password,email=email)
login(request,user)
return redirect('/userprofile/')# ЗАМЕНИТЬ
else:
form = SightUp()
context = {'form':form }
return render(request,'user.html',context)
Your user html had a problem, you didn't add the {% endfor %} tag that's why you are not seeing any information. Do something like so:
{% for i in detailsuser %}
<h1> yourname: i.email </h1>
{% endfor %}
<h1>Your last name:</h1>
<h1>Your nickname:</h1>
{% endfor %}

I ansewer it. Problem was because of cycle in my template

Related

Django derive model field based on other field value

I have a CustomUser model
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name = "email", max_length = 60, unique = True)
username = models.CharField(max_length = 30, unique = True)
I am using a User creation form to register new users as follows,
class RegistrationForm(UserCreationForm):
email = forms.EmailField(max_length = 60, help_text = "This will be your login.")
class Meta:
model = Account
fields = ("email", "username", "password1", "password2")
What I want to do is remove the "username" from the form fields, so
fields = ("email", "password1", "password2")
And then when the user submits the form, I wish to insert a value into the username field based on the email provided by the user, for e.g. email = abc#xyz.com, then username = abc.
How do I do this?
form.py
class UserCreateForm(UserCreationForm):
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields = ['email','first_name','last_name','password1','password2']
exclude = ['username']
widgets = {
'username':forms.TextInput(attrs={'class':'form-control'}),
# 'first_name':forms.TextInput(attrs={'class':'form-control'}),
# 'last_name':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),
}
view.py
def RegisterView(request):
if request.method == 'POST':
form = UserCreateForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
fm = form.save(commit=False)
fm.username = email.split("#")[0]
fm.save()
messages.success(request,f'{email} Successfully Registred')
form = UserCreateForm()
return render(request, 'index.html', {'form': form})
else:
form = UserCreateForm()
context = {'form': form, }
return render(request, 'index.html', context)
HTML Code
<form action="" method="post">
{% csrf_token %}
{% for i in form %}
<p>{{i.label}} {{i}}</p>
{% endfor %}
<button type="submit">Add</button>
</form>
Webpage output (register form)
admin panel

Django 3.0: Unable to get username in template

I have issue is that in template, I automatically get access of username of Superuser (if that is logged-in) but not username of user based on Buyer (Model). User is getting registered and also can login (I can see it in database). But in template I am unable to get username of user other than superuser. I don't what i am missing here. So i am putting all code of view.py here. Also after user logging he sees bookrepo:home and i am using user logic in header.html (bookrepo:home extends header.html)
I have model named Buyer in models.py file. And based on this model, two modelForm has made.
This is code of model.py
class Buyer(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(User, on_delete=models.DO_NOTHING)
# additional attributes
contact = models.CharField('Contact #', max_length=16, unique=True, validators=[
RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Phone number (Up to 15 digits) must be entered in the format: '+923001234567'."
),
], )
devices = models.CharField('Devices', unique=False, max_length=115, blank=True)
picture = models.ImageField(upload_to=profile_pic_path, null=True,blank=True)
def __str__(self):
return "{} {}".format(self.user.first_name, self.user.last_name)
class Meta:
get_latest_by = '-user.date_joined'
This is code of modelForms
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username',
'email',
'password')
def clean(self):
cleaned_data = super(RegistrationForm, self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError(
"Password and Confirm Password does not match"
)
class RegistrationFormPlus(forms.ModelForm):
class Meta():
model = Buyer
fields = ('contact',)
This is code of header.html (NOT the home.html)
{% if user.is_authenticated %}
<a class="nav-link" href="{% url 'bookrepo:logout' %}">Logout</a>
<h2>Welcome {{ user.username }}!</h2>
{% else %}
<a class="nav-link" href="{% url 'bookrepo:user_login' %}">Login</a>
{% endif %}
This is code of views.py
def home(req):
bookz = Book.objects.order_by('title')
var = {'books': bookz, 'range': 10}
return render(req, 'bookrepo/home.html', context=var)
def registration(request):
registered = False
if request.method == 'POST':
reg_form = RegistrationForm(data=request.POST)
reg_form_plus = RegistrationFormPlus(data=request.POST)
if reg_form.is_valid() and reg_form_plus.is_valid():
user = reg_form.save()
user.set_password(user.password)
user.save()
user_plus = reg_form_plus.save(commit=False)
user_plus.user = user
user_plus.save()
registered = True
else:
print(reg_form.errors, reg_form_plus.errors)
print("else 2 chala")
else:
reg_form = RegistrationForm()
reg_form_plus = RegistrationFormPlus()
return render(request, 'bookrepo/signup.html',
{'reg_form': reg_form,
'reg_form_plus': reg_form_plus,
'registered': registered
})
#login_required
def special(request):
return HttpResponse("You are logged in. Nice!")
#login_required
def user_logout(request):
logout(request)
return HttpResponseRedirect(reverse('bookrepo:home'))
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
return HttpResponseRedirect(reverse('bookrepo:home'))
else:
print("Someone tried to login and failed.")
print("They used username: {} and password: {}".format(username, password))
return HttpResponse("Invalid login details supplied.")
else:
return render(request, 'bookrepo/login.html', {})
You should use {{ buyer.user.username }} in your template to show the username of a user.
You are trying to extend your django user framework with a One To One Field . new extended Django Model used to store the extra information that relates to the User Model. {{user.username}} gives the username from session.
use this code to authenticate users don't forgot to import
from django.contrib.auth.models import User,auth
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user=auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect('index')
else:
messages.info(request,'invalid user')
return redirect('login')
else:
return render(request,"login.html")

Access data of a model linked through a OneToOneField model on a form

I want a pre-populated form with the details (e.g. first name and surname) about the profile of a logged-in user, so that they can update them. I have a custom user model with first name and surname in it, and then a profile model which is linked to the user model and extends it, containing some extra information.
I've defined a constant within the profile model which theoretically should get the user's first name and surname.
models.py:
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="email", unique=True, max_length=255)
first_name = models.CharField(max_length=30, blank=True, null=True)
surname = models.CharField(max_length=30, blank=True, null=True)
[...]
objects = UserManager()
[...]
Profile model added
class Profile(models.Model):
user = models.OneToOneField(User, related_name='current_user', on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def surname(self):
return self.user.surname}
def first_name(self):
return self.user.first_name
[...]
views.py:
#login_required
def profile_edit(request):
if request.method == 'POST':
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if p_form.is_valid():
p_form.save()
messages.success(request, f'Your account has been updated')
[...]
forms.py:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('first_name', 'surname')
template.html:
{% extends "base.html" %}
{% block content %}
<div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ p_form }}
<button class="button" type="submit"> User update</button>
</form>
</div>
{% endblock content %}
When accessing the template via the browser I expect to see the form already populated with the profile's (i.e. user's) first name and surname. Instead, I get a django.core.exceptions.FieldError: Unknown field(s) (surname, first_name) specified for Profile in the shell.
--
Answer
User ruddra's answer works fine, and I've flagged it as the answer to my problem. Nevertheless, declaring two different form objects and printing them out in the template would also work:
views.py:
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
forms.py:
class UserUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'surname')
class ProfileUpdateFormOld(forms.ModelForm):
class Meta:
model = Profile
fields = ('image',)
template.html:
{{ u_form }}
{{ p_form }}
Basically those fields are from User model, they are not in Profile model. So you can change the model class in ProfileUpdateForm to User:
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'surname')
Updated answer based on comments:
class ProfileUpdateForm(forms.ModelForm):
first_name = forms.CharField(max_length=255)
surname = forms.CharField(max_length=255)
def __init__(self, *args, **kwargs):
super(ProfileUpdateForm, self).__init__(*args, **kwargs)
self.initial['first_name'] = self.instance.first_name()
self.initial['surname'] = self.instance.surname()
class Meta:
model = Profile
fields = ('first_name', 'surname')
def save(self, *args, **kwargs):
user = self.instance.user
user.first_name = self.cleaned_data.get('first_name')
user.surname = self.cleaned_data.get('surname')
user.save()
return super(ProfileUpdateForm, self).save(*args, **kwargs)
Alternative to override the __init__(...) method is to send the initial data when initiating the form, pass the initial data. For example:
profile = request.user.profile
ProfileUpdateForm(instance=profile, initial={'first_name':profile.first_name(), 'surname': profile.surname()})

2nd Django form not rendering in HTML

I can not figure out what is happening here. I have two forms but the second one will not render any input fields to the template. The second form is in a different template than the first. I am still very new to programming but I have searched everywhere for an answer to this with no luck.
forms.py
from django import forms
class ContactForm(forms.Form):
contact_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Name*'}))
contact_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Email*'}))
contact_phone = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Phone Number*'}))
content = forms.CharField(
required=True,
widget=forms.Textarea(attrs={'placeholder': 'Your comments'})
)
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = ""
self.fields['contact_email'].label = ""
self.fields['contact_phone'].label = ""
self.fields['content'].label = ""
class EstimateForm(forms.Form):
contact_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Name*'}))
contact_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Email*'}))
contact_phone = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Your Phone Number*'}))
def __init__(self, *args, **kwargs):
super(EstimateForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = ""
self.fields['contact_email'].label = ""
self.fields['contact_phone'].label = ""
views.py
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
messages.success(request, 'Profile details updated.')
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
contact_phone = request.POST.get(
'contact_phone'
, '')
form_content = request.POST.get('content', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
'form_content': form_content,
})
content = template.render(context)
send_mail('Email from your website', content, context['contact_email'],
['email#gmail.com'],
fail_silently=False)
return redirect('/contact')
return render(request, 'main/contact.html', {
'form': form_class,
})
def estimate(request):
form_class = EstimateForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
contact_phone = request.POST.get(
'contact_phone'
, '')
# Email the profile with the
# contact information
template = get_template('estimate_template.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
})
content = template.render(context)
send_mail('Email from your website', content, context['contact_email'],
['email#gmail.com'],
fail_silently=False)
return redirect('main/index-v3.html')
return render(request, 'main/index-v3.html', {
'e_form': form_class,
})
template
<form role="form" action="" method="post" class="contact-form">
{% csrf_token %}
{{ e_form.as_p }}
<button type="submit" class="thm-btn">Submit</button>
</form>
This is what gets rendered in the page
<form role="form" action="" method="post" class="contact-form" style="margin-top: 25px" novalidate="novalidate">
<input type="hidden" name="csrfmiddlewaretoken" value="fsdSFKSDJDKFsdkfjJFKD">
<button type="submit" class="thm-btn">Submit</button>
</form>
You need to pass instance of form class instead of form class to template.
So change your code
return render(request, 'main/index-v3.html', {
'e_form': form_class(),
})

Django auth_user_model

I'd like to make auth_user_model login but I need to login with Email and Password. So I thought I can do that if I can save email value in 'username' field.
class HeepooUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=15, null=True)
allow_phone = models.BooleanField(default=False)
school = models.ForeignKey(School)
date_join = models.DateTimeField(auto_now_add=True)
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = RegisterForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save(commit=False)
user.set_password(user.password)
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile = profile_form.save()
registered = True
return HttpResponseRedirect("/books/")
else:
return HttpResponse('Wrong access1')
else:
user_form = UserForm()
profile_form = RegisterForm()
return render(request, "register.html", {
'user_form': user_form,
'profile_form': profile_form,
'registered': registered,
})
forms.py
class UserForm(forms.ModelForm):
email = forms.EmailField(max_length=50, required=True,
widget=forms.TextInput(attrs={'class':'form-control', }),
)
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('email', 'password',)
class RegisterForm(forms.ModelForm):
class Meta:
model = HeepooUser
exclude = ('allow_phone', 'user',)
Register.html
<form action="" method="post">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" value="Register">
</form>
Could you please help me on?
Thanks!
You can request the email instead of username to the user in your login form in order to use it for loggin him, then just generate a username for that user, you can do it using his email or name.
EDIT:
You only need to generate an username. Let's say that you are requesting name and last name to the user. Let's create a method to generate it.
def generate_username(first_name, last_name):
username = '%s.%s' % (first_name.lower(), last_name.lower())
username = '{:.29}'.format(username)
counter = User.objects.filter(first_name=first_name,last_name=last_name).count()
if counter > 0:
username += '%s' % (counter + 1)
return username
Then you can use it on your view.
user = user_form.save(commit=False)
user.set_password(user.password)
user.username = generate_username(first_name, last_name)
.....
If you don't want to request first name or last name, you can generate the username using his email too.