使用 Django FORM 自定义表单 API
Customize Form with Django FORM API
我目前正在使用 Django 框架创建一个 register/login 表单,因为我是这个框架的新手,所以我对 FORM API.
了解不多
我没有使用 FORM API,因为我不知道是否可以自定义它。
有什么方法可以将我的样式与 FORM API 一起使用吗?
作为现在的状态,我只是在创建自己的一个,而不使用 API,但是由于 FORM API 更安全并且可以更快地设置用户创建,我想使用它。
所以我的问题是,我可以使用 FORM API 实现自定义样式吗?包括<input>
,<div>
等..
这是我的 HTML 表格:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="limiter">
<div class="container-login100" style="background:black;">
<div class="wrap-login100">
<form class="login100-form validate-form" method='POST' action="{% url 'users:register' %}" >
{% csrf_token %}
<span class="login100-form-logo">
<i class="zmdi zmdi-landscape"></i>
</span>
<span class="login100-form-title p-b-34 p-t-27">
Register
</span>
<div class="wrap-input100 validate-input" data-validate = "Enter username">
<input class="input100" type="text" name="username" placeholder="Username" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter password">
<input class="input100" type="password" name="pass" placeholder="Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Confirm password">
<input class="input100" type="password" name="pass-confirm" placeholder="Confirm Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter Email">
<input class="input100" type="email" name="mail" placeholder="E-Mail" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="container-login100-form-btn">
<button class="login100-form-btn" type="submit" name="submit" value="submit">
Register
</button>
</div>
<div class="text-center p-t-90">
<a class="txt1" href="login">
Already registered?
</a>
</div>
</form>
</div>
</div>
</div>
这是我的 views.py 后端:
def register(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["pass"]
password_confirm = request.POST["pass-confirm"]
email = request.POST["mail"]
submit = request.POST["submit"]
print("UserName : ", username)
print('Email : ', email)
print('Password : ', password)
print('Password Confirm : ', password_confirm)
SpecialSym =['$', '@', '#', '%', '?']
confirm = False
if request.POST.get("submit"):
if len(username) < 7:
print('Username must be more than 10 char.')
confirm = False
messages.error(request, "Username must be more than 10 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(username) > 15:
print('Username must be less than 15 char.')
confirm = False
messages.error(request, "Username must be less than 15 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if any(char in SpecialSym for char in username):
print('Username can\'t contain special characters.')
confirm = False
messages.error(request, "Username can't contain special characters", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) < 8:
print("Your password is too short")
confirm = False
messages.error(request, "Your password is too short.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) > 25:
print("Your password must be less than 25 char")
confirm = False
messages.error(request, "Your password must be less than 25 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isdigit() for char in password):
print('Password should have at least one numeral')
confirm = False
messages.error(request, "Your password should have at least one numeral ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isupper() for char in password):
print('Password should have at least one uppercase letter')
confirm = False
messages.error(request, "Your password should have at least one uppercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.islower() for char in password):
print('Password should have at least one lowercase letter')
confirm = False
messages.error(request, "Your password should have at least one lowercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char in SpecialSym for char in password):
print('Password should have at least one of the symbols $@#?')
confirm = False
messages.error(request, "Your password should have at least one of these symbols: $@#? ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if (password != password_confirm):
print("Passwords don't match")
confirm = False
messages.error(request, "Passwords don't match.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if confirm == True:
messages.success(request, "Success! form submitted.", 'green')
return HttpResponseRedirect(reverse('users:register'))
return render(request, 'users/register.html')
可以使用in-builtUserCreationForm
[django-doc],在路径from django.contrib.auth.forms import UserCreationForm
.
现在,作为您当前的代码,您不需要使用 messages
框架,因为 in-built Form
已经有很多验证,您已经完成了。
在您的代码中,您可以通过以下方式实现,只需这样做:
我只提供了一个最小的可复制示例,因为模板中有很多 css
class,所以我只在每个字段中添加 my_class
,您可以添加自己的class,用Ctrl+U
或page source
即可看到。
urls.py
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('', views.register, name='home'),
path('success/', views.success, name='success')
]
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
from django.urls import reverse
from home.forms import MyUserCreationForm
def register(request):
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password1 = form.cleaned_data['password1']
email = form.cleaned_data['email']
user_data = User(username=username,
password=make_password(password1), email=email)
user_data.save()
return HttpResponseRedirect(reverse('users:success'))
else:
form = MyUserCreationForm()
return render(request, 'users/register.html', {'form': form})
def success(request):
return render(request, 'users/thanks.html')
forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth import password_validation
from django.utils.translation import gettext, gettext_lazy as _
from django.contrib.auth.models import User
class MyUserCreationForm(UserCreationForm):
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'password'}),
help_text=password_validation.password_validators_help_text_html(),
error_messages={'required': 'password is required'}
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'confirm password'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
error_messages={'required': 'password confirm is required'}
)
email = forms.CharField(widget=forms.EmailInput(
attrs={'class': 'my_class', 'placeholder': 'Email'}), error_messages={'required': 'Email is required'})
class Meta:
model = User
fields = ['username', 'email']
error_messages = {
'username': {'required': 'Username is required'},
}
widgets = {
'username': forms.TextInput(attrs={'class': 'myclass', 'placeholder': 'Username'}),
}
Note:
you can use any class in any field, you can change here for every field attrs={'class': 'my_class')
, I have used my_class
in every field just for example, you can view it in page source.
Note
: The example might be a bit complex, since I have inherited and changed the django's inbuilt form for adding css classes
.
register.html 或模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.red{
color:red;
font-size:1.15rem;
}
</style>
</head>
<body>
{% if form %}
<form method="POST" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<div class="red">
<p>{{error}}</p>
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<div>
{{field.label_tag}} {{field}}
<br>
{% for error in field.errors %}
<div class="red">
<span>{{error}}</span>
</div>
{% endfor %}
</div>
{% endfor %}
<input type="submit" value="Save">
</form>
{% else %}
<p>There is some error, form does not come from view.</p>
{% endif %}
</body>
</html>
thanks.html(提交成功后用于重定向)
<body>
<h2>You are now a user! logged in !</h2>
</body>
通过这个例子,你的数据已经成功保存在数据库中,你可以通过创建超级用户,通过python manage.py createsuperuser
并登录到管理站点,在Users
[=72]中看到它=].
基于class authentication views
[django-doc].
,上述工作可以变得更容易
我目前正在使用 Django 框架创建一个 register/login 表单,因为我是这个框架的新手,所以我对 FORM API.
了解不多我没有使用 FORM API,因为我不知道是否可以自定义它。 有什么方法可以将我的样式与 FORM API 一起使用吗? 作为现在的状态,我只是在创建自己的一个,而不使用 API,但是由于 FORM API 更安全并且可以更快地设置用户创建,我想使用它。
所以我的问题是,我可以使用 FORM API 实现自定义样式吗?包括<input>
,<div>
等..
这是我的 HTML 表格:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="limiter">
<div class="container-login100" style="background:black;">
<div class="wrap-login100">
<form class="login100-form validate-form" method='POST' action="{% url 'users:register' %}" >
{% csrf_token %}
<span class="login100-form-logo">
<i class="zmdi zmdi-landscape"></i>
</span>
<span class="login100-form-title p-b-34 p-t-27">
Register
</span>
<div class="wrap-input100 validate-input" data-validate = "Enter username">
<input class="input100" type="text" name="username" placeholder="Username" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter password">
<input class="input100" type="password" name="pass" placeholder="Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Confirm password">
<input class="input100" type="password" name="pass-confirm" placeholder="Confirm Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter Email">
<input class="input100" type="email" name="mail" placeholder="E-Mail" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="container-login100-form-btn">
<button class="login100-form-btn" type="submit" name="submit" value="submit">
Register
</button>
</div>
<div class="text-center p-t-90">
<a class="txt1" href="login">
Already registered?
</a>
</div>
</form>
</div>
</div>
</div>
这是我的 views.py 后端:
def register(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["pass"]
password_confirm = request.POST["pass-confirm"]
email = request.POST["mail"]
submit = request.POST["submit"]
print("UserName : ", username)
print('Email : ', email)
print('Password : ', password)
print('Password Confirm : ', password_confirm)
SpecialSym =['$', '@', '#', '%', '?']
confirm = False
if request.POST.get("submit"):
if len(username) < 7:
print('Username must be more than 10 char.')
confirm = False
messages.error(request, "Username must be more than 10 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(username) > 15:
print('Username must be less than 15 char.')
confirm = False
messages.error(request, "Username must be less than 15 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if any(char in SpecialSym for char in username):
print('Username can\'t contain special characters.')
confirm = False
messages.error(request, "Username can't contain special characters", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) < 8:
print("Your password is too short")
confirm = False
messages.error(request, "Your password is too short.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if len(password) > 25:
print("Your password must be less than 25 char")
confirm = False
messages.error(request, "Your password must be less than 25 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isdigit() for char in password):
print('Password should have at least one numeral')
confirm = False
messages.error(request, "Your password should have at least one numeral ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.isupper() for char in password):
print('Password should have at least one uppercase letter')
confirm = False
messages.error(request, "Your password should have at least one uppercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char.islower() for char in password):
print('Password should have at least one lowercase letter')
confirm = False
messages.error(request, "Your password should have at least one lowercase letter ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if not any(char in SpecialSym for char in password):
print('Password should have at least one of the symbols $@#?')
confirm = False
messages.error(request, "Your password should have at least one of these symbols: $@#? ", 'red')
return HttpResponseRedirect(reverse('users:register'))
if (password != password_confirm):
print("Passwords don't match")
confirm = False
messages.error(request, "Passwords don't match.", 'red')
return HttpResponseRedirect(reverse('users:register'))
if confirm == True:
messages.success(request, "Success! form submitted.", 'green')
return HttpResponseRedirect(reverse('users:register'))
return render(request, 'users/register.html')
可以使用in-builtUserCreationForm
[django-doc],在路径from django.contrib.auth.forms import UserCreationForm
.
现在,作为您当前的代码,您不需要使用 messages
框架,因为 in-built Form
已经有很多验证,您已经完成了。
在您的代码中,您可以通过以下方式实现,只需这样做:
我只提供了一个最小的可复制示例,因为模板中有很多 css
class,所以我只在每个字段中添加 my_class
,您可以添加自己的class,用Ctrl+U
或page source
即可看到。
urls.py
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('', views.register, name='home'),
path('success/', views.success, name='success')
]
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
from django.urls import reverse
from home.forms import MyUserCreationForm
def register(request):
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password1 = form.cleaned_data['password1']
email = form.cleaned_data['email']
user_data = User(username=username,
password=make_password(password1), email=email)
user_data.save()
return HttpResponseRedirect(reverse('users:success'))
else:
form = MyUserCreationForm()
return render(request, 'users/register.html', {'form': form})
def success(request):
return render(request, 'users/thanks.html')
forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth import password_validation
from django.utils.translation import gettext, gettext_lazy as _
from django.contrib.auth.models import User
class MyUserCreationForm(UserCreationForm):
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'password'}),
help_text=password_validation.password_validators_help_text_html(),
error_messages={'required': 'password is required'}
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(
attrs={'autocomplete': 'new-password', 'class': 'my_class', 'placeholder': 'confirm password'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
error_messages={'required': 'password confirm is required'}
)
email = forms.CharField(widget=forms.EmailInput(
attrs={'class': 'my_class', 'placeholder': 'Email'}), error_messages={'required': 'Email is required'})
class Meta:
model = User
fields = ['username', 'email']
error_messages = {
'username': {'required': 'Username is required'},
}
widgets = {
'username': forms.TextInput(attrs={'class': 'myclass', 'placeholder': 'Username'}),
}
Note:
you can use any class in any field, you can change here for every fieldattrs={'class': 'my_class')
, I have usedmy_class
in every field just for example, you can view it in page source.
Note
: The example might be a bit complex, since I have inherited and changed the django's inbuilt form for adding cssclasses
.
register.html 或模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.red{
color:red;
font-size:1.15rem;
}
</style>
</head>
<body>
{% if form %}
<form method="POST" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<div class="red">
<p>{{error}}</p>
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<div>
{{field.label_tag}} {{field}}
<br>
{% for error in field.errors %}
<div class="red">
<span>{{error}}</span>
</div>
{% endfor %}
</div>
{% endfor %}
<input type="submit" value="Save">
</form>
{% else %}
<p>There is some error, form does not come from view.</p>
{% endif %}
</body>
</html>
thanks.html(提交成功后用于重定向)
<body>
<h2>You are now a user! logged in !</h2>
</body>
通过这个例子,你的数据已经成功保存在数据库中,你可以通过创建超级用户,通过python manage.py createsuperuser
并登录到管理站点,在Users
[=72]中看到它=].
基于class authentication views
[django-doc].