this is my code:
views.py
class SignUpView(generic.CreateView):
form_class = SignUpForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
forms.py
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=30, required=True, help_text='Required.')
last_name = forms.CharField(max_length=30, required=True, help_text='Required.')
email = forms.EmailField(max_length=254, required=True , help_text='Required.')
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2',)
class ProfileForm(forms.ModelForm):
location = forms.CharField(max_length=200, required=True, help_text='Required.')
phone = forms.CharField(max_length=10, required=True, help_text='Required.')
class Meta:
model = Profile
fields = ('location','phone')
i don't know how to extend signupform with profileform, i want user to submit together since signup
You can do it like :-
forms.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=200)
password1 = forms.CharField(widget=forms.PasswordInput())
username = forms.CharField(help_text=False)
first_name = forms.CharField(max_length=25)
address = forms.CharField(max_length=200)
phone = forms.IntegerField()
gender = forms.ChoiceField(choices=GENDER_CHOICES)
age = forms.IntegerField()
class Meta:
model = User
fields = (
'first_name',
'address',
'phone',
'gender',
'age',
'email',
'username',
)
signup.html
{% extends "mains/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:signup_view' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Register</button>
</form>
{% endblock content %}
(The code is Successfully Tested and Worked)
You can also use Django Crispy Forms to look forms more beautiful and decent.
Related
I am trying to display all the categories to appear as a list that I can click and select from, just an exact replica of what I have in my admin panel, but it still display's as a list that isn't clickable.
forms.py
class ProfileEditForm(forms.ModelForm):
"""
Form for updating Profile data
"""
class Meta:
model = Profile
fields = [
"first_name",
"last_name",
"about_me",
"profile_image",
"username",
"email",
"categories",
]
first_name = forms.CharField(label="First Name", max_length=63, required=False)
last_name = forms.CharField(label="Last Name", max_length=63, required=False)
about_me = forms.CharField(label="About Me", max_length=511, required=False)
email = forms.EmailField(label="Email", disabled=True)
username = forms.CharField(label="Username", disabled=True)
profile_image = forms.ImageField(required=False)
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
profile.models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=63, blank=False)
last_name = models.CharField(max_length=63, blank=False)
about_me = models.CharField(max_length=511, blank=True)
categories = models.ManyToManyField(
Category, related_name="user_categories", symmetrical=False
)
categories.models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=63)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True, blank=True, null=True)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
settings.html
<div class='row'>
<div class="col s12 m6">
{{form.categories.errors}}
{{form.categories.label_tag}}
{{form.categories}}
</div>
</div>
What I hope to achieve
What I get
You need to create the form itself:
<form method='post'>
</form>
And print each field on a new line:
{{ form.as_p }}
is a security check.
{% csrf_token %}
In the view, I left get_context_data. In it, you can add values to the context, for example, like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['rubrics'] = Car.objects.all()
Replace bboard with the name of the folder where your templates are placed.
I have this: templates/bboard which are in the application folder.
In the view for the form, the CreateView class is used, in which: template_name - the name of the template for displaying the page, form_class - the form class is indicated, success_url - where to return in case of successful saving of the form (in this case, this is the same page with the form), get_context_data - the template context (you can print it out and see what's inside).
And if your model has fields: first_name, last_name, about_me, email, username, profile_image, then it is enough that you have specified the fields variable in the class Meta class. You don't need to re-create them in the form.
template_name = 'bboard/tam_form.html'#bboard replace with your prefix
Templates
<form method='post'>
{{form.categories.errors}}
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value='adding'>
</form>
views.py
from .forms import *
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
class Profile(CreateView):
template_name = 'bboard/settings.html'#bboard replace with your prefix
form_class = ProfileEditForm
success_url = reverse_lazy('test')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('test/', Profile.as_view(), name='test'),
]
Update 13.11.2022
This is how my form looks like when I go to the address:
http://localhost:8000/test/
But the form is not submitted. I don't have much experience with this. I can assume that forms.ModelForm expects that the model has such fields, because if you delete the lines with email, username, profile_image and also remove them from the fields and add 'user' to the field, then the data will be saved in the database (checked).
As I said earlier, if the fields are declared in fields, then you do not need to define them again (if you leave them, the form will also be saved). This is what the form class looks like:
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = [
'user',
'first_name',
'last_name',
'about_me',
'categories',
]
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
I have a feedback form and it should be located on the main page along with other models. But alas, for some reason it refers to a non-existent template. And thus it is not shown on the site, although the model itself is present in the admin panel.
Please help me figure it out.
I was trying many ways to figure out it, but theres nothing
views.py
class MainDetail(CreateView):
success_url = reverse_lazy('success_page')
form_class = ContactForm
def get(self, request, **kwargs):
search_query = request.GET.get('search', )
model_2 = Jobs.objects.order_by()
form = ContactForm(request.POST)
portfolio = Portfolio.objects.prefetch_related('image')
ctx = {
'jobs':model_2,
'portfolio': portfolio
}
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'homepage.html', ctx)
def form_valid(self, form):
# Формируем сообщение для отправки
data = form.data
subject = f'Сообщение от {data["first_name"]} {data["last_name"]},Тема: ORDER {data["phone"]}'
email(subject, data['message'])
return super().form_valid(form)
model.py
class Contact(models.Model):
first_name = models.CharField ('Name', max_length=25)
last_name = models.CharField('Last Name', max_length=30)
phone = models.EmailField ('Phone', max_length=15)
message = models.TextField (max_length=400)
class Meta:
verbose_name= 'Feedback'
verbose_name_plural = 'Feedsbacks'
def __str__(self):
class Meta:
verbose_name= 'Feedback'
verbose_name_plural = 'Feedsbacks'
def __str__(self):
return self.first_name
forms.py
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = ['first_name', 'last_name', 'phone', 'message']
widgets = {
'first_name': forms.TextInput (
attrs={'placeholder':'Name'}
),
'last_name': forms.TextInput(
attrs={'placeholder': 'Wash'}
),
'phone': forms.TextInput(
attrs={'placeholder': '+7 (123) 45-67-89'}
),
'message': Textarea(
attrs={
'placeholder': 'Message',
"rows":6,
"cols": 25
}
)
}
html
<aside class="postcard">
<form class="form" method="POST">
<p>Order</p>
{% csrf_token %}
{{ form.as_p }}
<div class="form-group">
<input type="submit" value="Send">
</div>
</form>
</aside>
Thanks for any help
Here it is the solution to all the troubles
class MainDetail(CreateView):
model = Jobs
model_2 = Portfolio
model_3 = Contact
template_name = 'homepage.html'
success_url = reverse_lazy('success_page')
form_class = ContactForm
def get_context_data(self, **kwargs):
context = super(MainDetail, self).get_context_data(**kwargs)
context['first_form'] = ContactForm (self.request.POST)
context['jobs'] = Jobs.objects.order_by()
context['portfolio'] = Portfolio.objects.prefetch_related('image')
return context
I am having a problem with getting some additional fields to show up on the website. I want to have the viewer be able to add their phone_number and their birth_date but the form that I created is not showing up. If anyone could give me some direction, been trying this for 3 days.
Code
.view.py
def Profile(request):
args = {'user': request.user}
return render(request, 'index/profile.html', {})
def update_profile(request, user_id):
user = User.objects.get(pk=user_id)
user.save()
class ProfileUpdateView(LoginRequiredMixin, TemplateView):
user_form = UserForm
profile_form = ProfileForm
template_name = 'profile.html'
def post(self, request):
post_data = request.POST or None
user_form = UserForm(post_data, instance=request.user)
profile_form = ProfileForm(post_data, instance=request.user.profile)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request, 'Your profile was successfully updated!')
return HttpResponseRedirect(reverse_lazy('profile'))
context = self.get_context_data(
user_form=user_form,
profile_form=profile_form
)
return self.render_to_response(context)
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
.model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.IntegerField(default="", editable=True)
birth_date = models.DateTimeField(null=True, blank=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
.form.py
from django import forms
from django.contrib.auth.models import User
from .models import Profile
from django.contrib.auth.forms import UserChangeForm
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control'}),
'last_name': forms.TextInput(attrs={'class': 'form-control'}),
'email': forms.TextInput(attrs={'class': 'form-control'}),
}
class UserUpdateForm(UserForm, UserChangeForm):
first_name = forms.CharField(
required=True, widget=forms.TextInput(attrs={'class': 'form-control'})
)
last_name = forms.CharField(
required=True, widget=forms.TextInput(attrs={'class': 'form-control'})
)
email = forms.EmailField(
required=True, widget=forms.TextInput(attrs={'class': 'form-control'})
)
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('phone_number', 'birth_date')
widgets = {
'phone_number': forms.TextInput(attrs={'class': 'form-control'}),
'birth_date': forms.TextInput(attrs={'class': 'form-control'}),
}
class ProfileUpdateForm(ProfileForm, UserChangeForm):
phone_number = forms.IntegerField(
required=True, widget=forms.TextInput(attrs={'class': 'form-control'})
)
birth_date = forms.CharField(
required=True, widget=forms.TextInput(attrs={'class': 'form-control'})
.profile.html
{% block body %}
<h2>{{ user.get_full_name }}</h2>
<p>Username: {{ user.username }}</p>
<p>Phone Number: {{ user.profile.phone_number }}</p>
<p>Birth Date: {{ user.profile.birth_date }}</p>
<div class="container">
<form method="post">
{{user_form.as_p}}
{{profile_form.as_p}}
<button type="submit">Submit</button>
</form>
<br>
</div>
OR,
<form method="post">
{{ user_form.as_p }}
{{ profile_form.as_p }}
<button type="submit">Save changes</button>
</form>
{% endblock %}
There is no place to enter the phone_number and birth_date
Took a 2 day break and came back to this issue.
The main issue was that I was trying to do too much and made it overly complex. Easy is the answer.
View.py
class Register(TemplateView):
template_name = 'registration.html'
def get(self, request, *args, **kwargs):
form = CreateForm()
return render(request, self.template_name, {'form': form})
#staticmethod
def post(request):
try:
data = request.POST.get
user = User(
first_name=data('first_name'),
last_name=data('last_name'),
username=data('username').strip(),
email=data('email'),
)
user.set_password(data('password').strip())
user.save()
request.session["user_id"] = user.id
return HttpResponse(' Save successfully ')
except Exception as c:
return HttpResponse("Failed : {}".format(c), 500)
Form.py
role_choice= (("Customer", "Customer"), ("Employee", "Employee"))
class CreateForm(forms.Form):
first_name = forms.CharField(label="Enter Your First Name", max_length=30, required=True)
last_name = forms.CharField(label="Enter Your Last Name", max_length=30, required=True)
username = forms.CharField(required=True, widget=forms.TextInput())
email = forms.CharField(required=True, widget=forms.TextInput())
password = forms.CharField(required=True, widget=forms.PasswordInput())
role = forms.ChoiceField(choices=role_choice, widget=forms.RadioSelect())
class Customer(forms.Form):
contact = forms.IntegerField(label="Enter your contact number", required=True, )
amount = forms.IntegerField(required=True, min_value=500)
type = forms.ChoiceField(choices=choice)
Model.py
class Customers(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
contact = models.BigIntegerField()
amount = models.BigIntegerField()
type = models.CharField(max_length=1)
Template
{% extends "home.html" %}
{% load crispy_forms_tags %}
{% block title %}Create Account{% endblock %}
{% block content %}
<div>
{% csrf_token %}
{{ form|crispy }}
<button type="submit">Submit</button><br>
</div>
{% endblock %}
After the registration when user select customer option after sumbit the form i go to customer page if user select employee option he/she go to employee page but i don't know how to do this
First of all, I strongly advice not to write all the views, etc. yourself. Django already has a lot of tooling inplace. It has a UserCreationForm [Django-doc] that can be slighly modified. For example:
# app/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
class RoleUserCreationForm(UserCreationForm):
ROLES = (
('Customer', 'Customer'),
('Employee', 'Employee')
)
role = forms.ChoiceField(choices=ROLES, widget=forms.RadioSelect())
class Meta(UserCreationForm.Meta):
fields = (*UserCreationForm.Meta.fields, 'first_name', 'last_name')
We can here thus add the extra fields for first_name and last_name as well.
Now we can make use of this in a CreateView [Django-doc], and override the form_valid(..) method [Django-doc]:
# app/views.py
from app.forms import RoleUserCreationForm
from django.contrib.auth import get_user_model
from django.shortcuts import redirect
from django.views.generic.edit import CreateView
class RegisterView(CreateView):
model = get_user_model()
form_class = RoleUserCreationForm
def form_valid(self, form):
request.session['user_id'] = self.object.id
if form.cleaned_data['role'] == 'Customer':
return redirect('name-of-customer-view')
else:
return redirect('name-of-employee-view')
Where you replace the 'name-of-customer-view' and 'name-of-employee-view' with the name of these views respectively.
So I have a student model which inherits from AbstractUser. I used 2 forms in one view for registration since I needed email, name and surname to be in my student database (as well as other fields). Now I'm trying to make an update profile view, with 2 forms that I made especially for updating the info. But I think I'm getting it wrong.. might need a little help here. I need the student to be able to update his email (which is from User model) and his photo, phone, name and surname (which are in Student model).
<form method="POST" action="{% url 'profile_edit' %}" class="" >
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
def profile_edit(request):
user = request.user
form1 = UserEditForm(request.POST or None, initial={'email': user.email,
})
form2 = StudentEditForm(request.POST or None, initial={'name': user.student.name,
'surname': user.student.surname,
'phone': user.student.phone,
'photo': user.student.photo})
if request.method == 'POST':
if form1.is_valid() and form2.is_valid():
user.email = request.POST['name']
user.student.name = request.POST['name']
user.student.surname = request.POST['surname']
user.student.phone = request.POST['phone']
user.student.photo = request.POST['photo']
user.save()
return render(request, 'index.html')
context = {
"form1": form1,
"form2": form2
}
return render(request, "registration/profile_edit.html", context)
class UserForm(forms.ModelForm):
email = forms.EmailField(required=True)
password = forms.CharField(label='Password', max_length=32, required=True, widget=forms.PasswordInput)
confirm_password = forms.CharField(label='Confirm', max_length=32, required=True, widget=forms.PasswordInput,
help_text="Passwords must match!")
class StudentForm(forms.ModelForm):
name = forms.CharField(max_length=30, required=True)
surname = forms.CharField(max_length=50, required=True)
student_ID = forms.CharField(required=True, max_length=14, min_length=14)
photo = forms.ImageField(required=True)
phone = forms.CharField(max_length=15, required=True)
class Meta:
model = Student
fields = ('name', 'surname', 'phone', 'student_ID', 'photo')
class UserEditForm(forms.ModelForm):
email = forms.EmailField(required=False)
class Meta:
model = User
fields = ('email',)
class StudentEditForm(forms.ModelForm):
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 = ('name', 'surname', 'phone', 'photo')
Problem is that I am getting no form, so I am either doing something wrong in the view, either the forms.
<form method="POST" action="{% url 'profile_edit' %}" class="" >
{% csrf_token %}
{{ form1.as_p }}
{{ form2.as_p }}
<button type="submit">Save</button>
</form>
according to your context the names of your forms are form1 and form2, so form only wont display any form
You don't need two forms. I have answered your previous question which led to this question.
It will save you from a lot of unnecessary Code.