I have a registration form made of 2 forms, from which email field gets saved in both User and Student models. Now, I made an update account info view. Problem is, I want that email will get updated the in both models. But I get error:
'StudentEditForm' object has no attribute 'email'
Here is my code:
class StudentEditForm(forms.ModelForm):
email = forms.EmailField(required=False)
name = forms.CharField(max_length=30)
surname = forms.CharField(max_length=50)
photo = forms.ImageField(required=False)
phone = forms.CharField(max_length=15, required=False)
class Meta:
model = Student
fields = ('email', 'name', 'surname', 'phone', 'photo')
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=30, null=True, blank=True, default=None)
surname = models.CharField(max_length=50, null=True, blank=True, default=None)
email = models.EmailField(unique=True, null=True, blank=True, default=None)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')],
null=True, blank=True, default=None)
photo = models.ImageField(upload_to='students_images', null=True, blank=True, default=None)
phone = models.CharField(max_length=15, null=True, blank=True, default=None)
def __str__(self):
return self.surname
User.student = property(lambda p: Student.objects.get_or_create(user=p)[0])
def profile_edit(request):
user = request.user
student = request.user.student
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
user.email = form.email
form.save()
return render(request, 'index.html')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
Again, I need that I will be able to update the email fields. And the email will get saved in User email but also I want it saved to Student email.
call form.is_valid() and then use form.cleaned_data['email'], see https://docs.djangoproject.com/en/1.11/topics/forms/
I had to add
form.is_valid()
and
user.email = form.cleaned_data['email']
but also to add user.save() which solved this issue.
Related
#HELP in python (DJANGO 4)
I send this message here because I have not been able to find an answer elsewhere.
Currently I’m on a project where I have to create a booking form.
The goal is that when the user submit the Reservation form, I send the data in BDD, and I retrieve the user's id by a relation (ForeignKey).
And my difficulty is in this point precisely, when I send my form in BDD I recover the information, except the id of the user…
I did a Foreignkey relationship between my 2 tables and I see the relationship in BDD but I don’t receive the id of the User table, but null in the place….
Does anyone of you know how to help me please?
Thank you all.
--My model.py --
class Reservation(models.Model):
fullName = models.CharField('Nom Complet', max_length=250, null=True)
adress = models.CharField('Adresse', max_length=100, null=True)
zip_code = models.IntegerField('Code Postal', null=True)
city = models.CharField('Vile', max_length=100, null=True)
email = models.EmailField('Email', max_length=250, null=True)
phone = models.CharField('Telephone', max_length=20, null=False)
date = models.CharField('Date', max_length=20, null=True, blank=True)
hour = models.CharField('Heure', max_length=20, null=True, blank=True)
message = models.TextField('Message', null=True)
accepted = models.BooleanField('Valide', null=True)
created_at = models.DateTimeField('Date Creation', auto_now_add=True, null=True)
modified_at = models.DateTimeField('Date Mise Jour', auto_now=True, null=True)
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.fullName
-- my views.py --
#login_required()
def user_new_reservation(request, pk=None):
user = User.objects.get(id=pk)
if request.method == 'POST':
form = ReservationForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Votre réservation a bien été envoyé!')
return redirect('reservation:user_reservation', pk=request.user.id)
else:
form = ReservationForm()
context = {'form': form}
return render(request, 'reservation/new_reservation.html', context)
-- My Form.py --
class ReservationForm(forms.ModelForm):
class Meta:
model = Reservation
fields = [
'fullName',
'adress',
'zip_code',
'city',
'email',
'phone',
'date',
'hour',
'message',
]
Thank you all.
Inside your form.save use:
user = form.save(commit=False)
user.user = request.user
user.save()
user=your field name in your model
request user= in django when you use authentication you can access some of information based on request like user and other
Good luck
I have Rank, UserProfile and Company models. These classes are connected with foreign keys. A user with Rank "Lead" can create new users from his dashboard. I want to filter Rank models according to UserProfile's company. In the sign up form there will be dropdown list to choose Rank for new user. There should only be ranks that belong to UserProfile's company. These are my models:
class CompanyProfile(models.Model):
comp_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
comp_name = models.CharField(max_length=200)
country = models.CharField(max_length=200, default='')
def __str__(self):
return self.comp_name
class Rank(models.Model):
rank_name = models.CharField(max_length=200)
company = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True, unique=False)
def __str__(self):
return self.rank_name
class UserProfile(AbstractUser):
company = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True, unique=False)
user_id = models.UUIDField(default=uuid.uuid4(), editable=False, unique=True)
username = models.CharField(max_length=500, unique=True)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
password = models.CharField(max_length=250)
email = models.EmailField(max_length=254)
rank = models.ForeignKey(Rank, on_delete=models.CASCADE, null=True, unique=False)
image = models.ImageField(upload_to='profile_image', blank=True, null= True, default='profile.png')
def __str__(self):
return self.username
This is my form:
class SignUpForm(forms.ModelForm):
password1 = forms.CharField(max_length=250)
password2 = forms.CharField(max_length=250)
class Meta:
model = UserProfile
fields = (
'username', 'first_name', 'last_name', 'email', 'password1', 'password2','rank', 'image')
And this is views.py:
#user_passes_test(is_lead)
#login_required
def signup(request):
form_class = SignUpForm
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid() :
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.is_active = False
if form.cleaned_data['password1'] != "":
user.set_password(form.cleaned_data['password1'])
user.save()
return redirect('home')
else:
form = form_class()
return render(request, 'signup.html', {'form': form})
You'll need to override rank in your SignUpForm.
Something along the lines of:
choices = [(rank.id, rank.name) for rank in Rank.objects.filter(company=...)]
rank = models.CharField(
max_length=200,
choices=choices,
)
I assume you're passing the company into the form somehow so you'll need to adjust the filter to filter for the company you're creating the profile for.
I am using a custom User model. And I have another Customer model. I want the user field will only show the staff user no other type of user in the field will show in the registration form. In my case, it is showing all types of users whether it is staff or customer or a service user.
Models.py
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True)
email = models.EmailField(max_length=254, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_Customer = models.BooleanField(default=False)
is_Service_Provider = models.BooleanField(default=False)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % self.pk
def get_username(self):
return self.username
class Customer(models.Model):
user = models.OneToOneField('accounts.User', on_delete=models.SET_NULL, null=True)
email = models.EmailField(max_length=254, null=False)
date_Of_Birth = models.DateField(null=False)
country = models.ForeignKey('accounts.Country', null=True, on_delete=models.SET_NULL, related_name='Country')
state = models.ForeignKey('accounts.State', null=True, on_delete=models.SET_NULL, related_name='State')
city = models.ForeignKey('accounts.City', null=True, on_delete=models.SET_NULL, related_name='city')
address = models.CharField(max_length=254, null=False)
refernce_by_person_name = models.CharField(max_length=254, null=True)
refernce_by_person_contact_no = models.IntegerField(null=True)
phone_no = models.IntegerField(null=False)
alternate_no = models.IntegerField(null=False)
hobbies = models.CharField(max_length=254)
def __str__(self):
return self.user.username
views.py
def form(request):
forms = CustomerRegistrationForm()
if request.method == "POST":
forms = CustomerRegistrationForm(request.POST)
if forms.is_valid():
forms.save()
return redirect('/customer/show')
context = {
'forms' : forms,
}
return render(request,'customer/form.html', context)
forms.py
class CustomerRegistrationForm(forms.ModelForm):
class Meta:
model = Customer
fields = '__all__'
You can filter the staff users in the form like this.
class CustomerRegistrationForm(forms.ModelForm):
user = forms.ModelChoiceField(queryset=User.objects.filter(is_staff=True))
class Meta:
model = Customer
fields = ['user','email','date_of_birth',...]
I am a beginner in django. When admin creates a user, I am trying to save some fields in EmailAddress model.But for some reason the email field is always blank. Is there any way I can update the instance with email in UserProfile or EmailAddress model.
models.py looks like this
User._meta.get_field('email').blank = False
User._meta.get_field('email')._unique = True
class EmailAddress(models.Model):
user = models.OneToOneField(User, unique=True, related_name ='address')
email = models.EmailField()
verified = models.BooleanField(verbose_name=_('verified'), default=True)
primary = models.BooleanField(verbose_name=_('primary'), default=True)
class Meta:
db_table = 'account_emailaddress'
class UserProfile(models.Model, HashedPk):
user = models.OneToOneField(User, unique=True, related_name ='profile')
job_title = models.CharField(max_length=128, blank=True, null=False, default="")
website = models.URLField(max_length=255, blank=True, null=True)
organisation = models.CharField(max_length=50, blank=True, null=True, default="")
phone_number = PhoneNumberField( blank=True, null=True)
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
EmailAddress.objects.create(user=instance)
forms.py looks like this --
class SignUpForm(forms.Form):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
phone_number = PhoneNumberField(label=_("Phone (Please state your country code eg. +44)"))
organisation = forms.CharField(max_length=50)
email = forms.EmailField()
password1 = forms.CharField(max_length=20)
password2 = forms.CharField(max_length=20)
captcha = ReCaptchaField(attrs={'theme' : 'clean'})
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
up = user.profile
up.phone_number = self.cleaned_data['phone_number']
up.organisation = self.cleaned_data['organisation']
user.save()
up.save()
Any help is highly appreciated.
Sorted. It needs to be
EmailAddress.objects.create(user=instance, email=instance.email)
I have custom user model by extending AbstractUser class. I want to make form to change user's fullname and website field.
My user:
class Hacker(AbstractUser):
name = models.CharField(max_length=255)
team = models.ForeignKey(Team, on_delete=models.CASCADE, blank=True, null=True)
description = models.CharField(max_length=255, blank=True, null=True)
website = models.URLField(max_length=200, blank=True, null=True)
def __str__(self):
if self.name:
return self.name
else:
return self.username
And forms.py:
class ProfileForm(forms.ModelForm):
"""
Edit profile form
"""
name = forms.CharField(label=_("Name"),
widget=forms.TextInput(attrs={'placeholder': _('Name')}))
description = forms.CharField(label=_("Description,Position"), required=False,
widget=forms.TextInput(attrs={'placeholder': _('Description, Position')}))
website = forms.URLField(label=_("Website"), required=False,
widget=forms.TextInput(attrs={'placeholder': _('Website URL')}))
class Meta:
model = get_user_model()
fields = ['name', 'description', 'website']
In page I use {{ field }} to add inputs and in POST part of views:
form = ProfileForm(request.POST)
if form.is_valid():
form.save(commit=True)
...
But form.save gives UNIQUE constraint failed: common_hacker.username error. What can be problem here?
Adding instance=request.user when creating form fixed problem:
form = ProfileForm(request.POST, instance=request.user)