Properly configuring user registration using 2 forms - python

I am trying to submit 2 forms at a time to create my student user in Django. I have been struggling for a while now, but I think I'm finally closing to an end on how to manage 2 forms at a time for my users to register. But when I fill in the data and then click register, I get error: "This field is required." under my student ID field. What am I doing wrong ? Thanks.
class UserForm(forms.ModelForm):
password = forms.CharField(
label='Password',
max_length=32,
required=True,
widget=forms.PasswordInput,
)
password2 = forms.CharField(
label='Confirm',
max_length=32,
required=True,
widget=forms.PasswordInput,
help_text="Make sure they match!",
)
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'password', 'password2')
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('phone', 'student_ID', 'photo')
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_user_student(sender, instance, created, **kwargs):
if created:
Student.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_student(sender, instance, **kwargs):
instance.profile.save()
#csrf_protect
def student_register(request):
if request.method == 'POST':
form1 = UserForm(request.POST, prefix="user")
form2 = StudentForm(request.POST, prefix="profile")
if form1.is_valid() and form2.is_valid():
# create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
# create entry for UserProfile (extension of new_user object)
profile = form2.save(commit=False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("index")
else:
form1 = UserForm(prefix="user")
form2 = StudentForm(prefix="profile")
c = {
'form1': form1,
'form2': form2,
}
return render(request, "student_signup_form.html", c)
<form method="post">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>

First, you don't need #csrf_protect if you use {% csrf_token %} in template.
Second, you are probably getting student_ID required because you are trying to create a profile in signal providing just the user.
You can change your models like this:
models.py
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
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.user.username
views.py
def student_register(request):
data = dict()
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = StudentForm(request.POST, request.FILES)
if form1.is_valid() and form2.is_valid():
cd1 = form1.cleaned_data
username = cd1["username"]
password = cd1["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
cd2 = form2.cleaned_data
phone = cd2['phone']
student_ID = cd2['student_ID']
photo = cd2['photo']
Student.objects.create(user=new_user, phone=phone, student_ID=student_ID, photo=photo)
return redirect('index')
else:
form1 = UserForm()
form2 = StudentForm()
data['form1'] = form1
data['form2] = form2
return render(request, "student_signup_form.html", data)
template
<form action='' method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>

You can make StudentForm class a derived class of UserForm by declaring like class StudentForm(UserForm): and just submit one form that is StudentForm
It can be done like this also,
#models.py
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User)
student_ID = models.CharField(unique=True, max_length=14,validators=[RegexValidator(regex='^.{14}$',message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
User.student = property(lambda u: Student.objects.get_or_create(user=u)[0])
#forms.py
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('student_ID', 'photo', 'phone', )
#views.py
def student_register(request):
template_name = "student_signup_form.html"
context = {}
if request.method == 'POST':)
form = StudentForm(request.POST, instance=request.user.student)
if form.is_valid():
object = request.user.student
object.student_ID= form.cleaned_data['student_ID']
object.photo = form.cleaned_data['photo']
object.phone = form.cleaned_data['phone']
object.save()
return HttpResponseRedirect('index')
else:
form = StudentForm()
context['form'] = form
return render(request, template_name, context)

Related

Form is not saving in database when submitted

I am working on a project on Django, where user can input values on form and submit using POST request. When form is submitted, datas are not saved in database. How do I implement save data when form is submitted.
Models:
class DataInfo(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
beneficiary_name = models.CharField(max_length=250, blank=True)
beneficiary_bank_name = models.CharField(max_length=250, blank=True)
beneficiary_account_no = models.CharField(max_length=250, blank=True)
beneficiary_iban = models.CharField(max_length=250, blank=True)
beneficiary_routing_no = models.CharField(max_length=250, blank=True)
amount = models.IntegerField(blank=True)
date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'DataInfo'
verbose_name_plural = 'DataInfo'
ordering = ['-date']
'''Method to filter database results'''
def __str__(self):
return self.user.username
Views:
#login_required
def TransferView(request):
form = DataForm(request.POST)
if request.method == "POST":
if form.is_valid():
pp = form.save(commit=False)
pp.user = request.user
pp.save()
return redirect('site:transfer_cot')
else:
form = DataForm()
context = {
'form':form
}
return render(request, 'transfer.html', context)
Forms:
class DataForm(forms.ModelForm):
class Meta:
model = DataInfo
fields = ('beneficiary_name', 'beneficiary_bank_name', 'beneficiary_account_no', 'beneficiary_iban', 'beneficiary_routing_no', 'amount')
Template:
<form method="POST" action="{% url 'site:transfer_cot' %}">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-secondary">Submit</button>
</form>

Related to user object ain't beeing created Django

thanks for your time:
i've been having a problem on my POST request its getting me de code 302.0
it should create a object that is related to the user that did the request:
views.py:
#login_required
#transaction.atomic
def parceiros_create(request):
if request.method == 'POST':
form = ParceirosForm(request.POST, instance=request.user.parceiros)
if form.is_valid():
form.save()
messages.success(request, ('Parceiro criado'))
return redirect('home2')
else:
messages.error(request, ('Please correct the error below.'))
else:
form = ParceirosForm(instance=request.user)
context = {
'form': form,
}
return render (request, 'parceiroform.html', context)
forms.py:
class ParceirosForm(forms.ModelForm):
nome = forms.CharField(max_length=200)
endereco = forms.TextInput()
responsavel = forms.CharField(max_length=100)
tel = PhoneField(max_length=12)
class Meta:
prefix = 'parceiro'
model = Parceiros
fields = ['nome', 'endereco', 'responsavel', 'tel']
models.py:
get_user_model = User
class Parceiros (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nome = models.CharField(max_length=200)
endereco = models.TextField(max_length=400, blank=True)
responsavel = models.CharField(max_length=100)
tel = PhoneField(max_length=12)
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
ativo = models.BooleanField(default=False)
def __str__(self):
return '%s %s' % (self.user, self.nome)
parceiroform.html:
{% extends 'base.html' %}
{% block content %}
<h1>ok</h1>
<h1>OK</h1>
<h1>ok</h1>
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Save</button>
</form>
{% endblock %}
i'm getting the message (parceiro criado) on my admin although ain't creating any object(Parceiros).
You are not handling the user so change it like this
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
....

Drop down field shows values of all users

I have a form field in Django called Label. My problem is that the field shows the Labels of all users while I only want to show self created labels.
models
class Label(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
tag = models.CharField(max_length=25)
def __str__(self):
return self.tag
class Birthday(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=25, default="")
day = models.DateField()
label = models.ForeignKey(Label, on_delete=models.SET_NULL, default=0, null=True, blank=True)
def __str__(self):
return self.name
forms
class BirthdayForm(forms.ModelForm):
class Meta:
model = Birthday
fields = ('name', 'day', 'label')
class LabelForm(forms.ModelForm):
class Meta:
model = Label
fields = ('tag',)
template
<form method="POST">{% csrf_token %}
<table border="0">
{{ form }}
</table>
<button class="submitButton" type="submit">Submit</button>
</form>
This is the view for this template
view
#login_required
def index(request):
if request.method == "POST":
form = BirthdayForm(request.POST)
if form.is_valid():
birthday = form.save(commit=False)
birthday.user = request.user
birthday.save()
return redirect('index')
else:
#default_labels("Friend", request)
#default_labels("Family", request)
form = BirthdayForm()
birthday = Birthday.objects.filter(user=request.user)
username = request.user
return render(request, 'bd_calendar/index.html', {'form': form, 'birthday': birthday, 'username': username })

How to get manytomanyfield model data in View in Django

models.py
class Account(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
id = models.CharField(max_length=50, unique=True)
pw = models.CharField(max_length=200)
nick = models.CharField(max_length=50, blank=True)
blog = models.URLField(null=True, blank=True)
published_date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.published_date = timezone.now()
self.pw = make_password(self.pw)
super(Account, self).save(*args, **kwargs)
def __str__(self):
return self.id
class Meta:
ordering = ["-published_date"]
class Task(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
account = models.ManyToManyField(Account)
published_date = models.DateTimeField(default=timezone.now)
def publish(self):
self.published_date = timezone.now()
self.save()
forms.py
classAccountForm(forms.ModelForm):
class Meta:
model = NaverAccount
fields = ('id', 'pw', 'nick','blog',)
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ('account',)
task.html
<form action="#" class="form-horizontal" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Save</button>
views.py
def task(request):
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
#1. id = str(from Account model)
#2. pw = str(from Account model)
post.save()
form.save_m2m()
return redirect('task')
else:
form = TaskForm()
context = {'form': form}
return render(request, 'work/task.html', context)
I'm making small task app.
I want to get model data that user select(Account) from template in view.
ex) user can select 'id1', 'id2'.
and I want to get id, pw value in view.
so I can play small task with using id, pw in view
I tried to test some code in view like print(post.account) but can't go further.
1. id = str(from Account model)
2. pw = str(from Account model)

How do i get user profile in django 1.7

I want to fetch each and every detail of user profile. I know function get_profile() has been depreciated.
I want get user profile and then pass it as context to template.
Actually I am making a "Edit user profile" functionality.
My Model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
state = models.CharField(max_length=200, blank=True)
country = models.CharField(max_length=200, blank=True)
zipcode = models.CharField(max_length=200, blank=True)
And views:
#login_required
def dashboard(request):
context = RequestContext(request)
profile = request.user.userprofile
context_dict = {'profile': profile}
return render_to_response('appname/dashboard.html', context_dict, context)
To edit both User and Profile instance you have to use two forms:
class UserForm(forms.ModelForm):
class Meta:
class = User
fields = ('username', 'first_name', 'last_name')
class ProfileForm(forms.ModelForm):
class Meta:
class = UserProfile
exclude = ('user', )
#login_required
def edit_profile(request):
user = request.user
profile = user.userprofile
if request.method == 'POST':
user_form = UserForm(request.POST, instance=user)
profile_form = ProfileForm(request.POST, instance=profile)
if all([user_form.is_valid(), profile_form.is_valid()]):
user_form.save()
profile_form.save()
return redirect('.')
else:
user_form = UserForm(instance=user)
profile_form = ProfileForm(instance=profile)
return render(request, 'user_profile.html',
{'user_form': user_form, 'profile_form': profile_form})
And the template should contain both forms in the single <form> tag:
<form action="." method="POST">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<button>Update</button>
</form>

Categories