在 Django (1.11) 中为表单编辑默认字段的 help_text
Editing default fields' help_text for form in Django (1.11)
在过去的几天里,我一直在尝试使用我创建的用于处理用户注册的表单上的默认值 help_text
来解决一个奇怪的问题。当我看到 html django 正在插入时,我第一次注意到这个问题,因为默认的 help_text
正在被转义。
Screenshot of Issue
不是显示 <ul>
,我提醒你这是 django 包含的密码字段的默认 help_text
,而是显示纯文本。
所以这是我第一次注意到一定是做错了什么。如果默认形式 help_text
被转义并且看起来很糟糕,我显然犯了一个错误。接下来我将解释我为解决此问题所做的工作,然后将概述 model
、form
、view
和 template
以便你们有所了解开始工作。
我在网上找到的第一个解决方案是使用Meta
class,所以我在我的forms.py
下修改了class SignUpForm:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
company = forms.CharField()
city = forms.CharField()
state = forms.CharField()
zip = forms.IntegerField()
address = forms.CharField()
phone = forms.IntegerField()
class Meta:
model = User
# help_text = mark_safe
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
labels = {
'state': 'US States',
'password1': 'passcode1',
'password2': 'passcode2',
'username': 'human person',
'email': 'telegraph',
'city': 'locality',
'phone': "tele",
}
help_texts = {
'password1': 'Something that doesnt look awful',
'password2': 'Something else',
'username': 'Please enter an appropriate human name.',
'email': 'Which office?',
'city': 'What county?',
'phone': 'Please Include Country Code',
}
这就是我开始意识到问题比我想象的要严重的地方。不仅是导致 help_text
被转义的原因,其中一些字段接受我的更改,而另一些则不接受。我扩展默认值 UserCreationForm
的自定义字段(在此示例中 city
和 phone
不显示其新的 label
或 help_text
,而默认字段 username
和 email
都显示其空洞的新 label
和 help_text
。最重要的是 password1
和 password2
字段仍然存在不变。
Screenshot of class Meta result
好吧,那是行不通的。将其硬编码到表单中怎么样?好吧,事实证明这大部分是有效的,但在这个例子中它给我带来了另一个层次的复杂性,并且感觉像是不好的做法。我来解释一下。
因为我的表单扩展了默认的 django UserCreationForm
我实际上并没有在我的 SignUpForm
中设置字段,它们是自动添加的并且我在 class Meta:
中使用它们的字段所以为了硬编码解决这个问题,我必须添加它们。
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.safestring import mark_safe
class SignUpForm(UserCreationForm):
username = forms.CharField(help_text=mark_safe("Please enter an appropriate human name."), label='human name')
email = forms.CharField(widget=forms.EmailInput, help_text=mark_safe('Which office?'), label='telegraph')
password1 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something that doesnt look awful'),
label='Passcode')
password2 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something else'), label='Passcode 2')
company = forms.CharField(help_text=mark_safe("Please enter a company name"))
city = forms.CharField(help_text=mark_safe('What county?'), label='locality')
state = forms.CharField(help_text=mark_safe('Please enter the state'))
zip = forms.IntegerField(help_text=mark_safe('Please enter a zip code.'))
address = forms.CharField(help_text=mark_safe('Please enter an address.'))
phone = forms.IntegerField(help_text=mark_safe('Please include country code.'), label='tele')
class Meta:
model = User
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
所以这个可行,但它确实不切实际且令人担忧,因为我还没有解决根本问题。
硬编码结果的屏幕截图(不能post因为我没有足够的代表,但相信我一切正常)
所以这就把我们带到了现在,我已经尝试了一些其他的东西,但是没有什么比硬编码更接近我想要的东西了,所以我需要找出我犯的潜在错误。
所以这是我正在使用的:
models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
username = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.TextField(max_length=500, blank=True)
city = models.CharField(max_length=100, blank=True)
state = models.CharField(max_length=100, blank=True)
zip = models.CharField(max_length=5, blank=True)
address = models.CharField(max_length=200, blank=True)
phone = models.CharField(max_length=12, blank=True)
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
forms.py(当前硬编码版本):
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.safestring import mark_safe
class SignUpForm(UserCreationForm):
username = forms.CharField(help_text=mark_safe("Please enter an appropriate human name."), label='human name')
email = forms.CharField(widget=forms.EmailInput, help_text=mark_safe('Which office?'), label='telegraph')
password1 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something that doesnt look awful'),
label='Passcode')
password2 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something else'), label='Passcode 2')
company = forms.CharField(help_text=mark_safe("Please enter a company name"))
city = forms.CharField(help_text=mark_safe('What county?'), label='locality')
state = forms.CharField(help_text=mark_safe('Please enter the state'))
zip = forms.IntegerField(help_text=mark_safe('Please enter a zip code.'))
address = forms.CharField(help_text=mark_safe('Please enter an address.'))
phone = forms.IntegerField(help_text=mark_safe('Please include country code.'), label='tele')
class Meta:
model = User
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from apps.dashboard.forms import SignUpForm
def signup(request):
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.profile.company = form.cleaned_data.get('company')
user.profile.city = form.cleaned_data.get('city')
user.profile.state = form.cleaned_data.get('state')
user.profile.zip = form.cleaned_data.get('zip')
user.profile.address = form.cleaned_data.get('address')
user.profile.phone = form.cleaned_data.get('phone')
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect(main)
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
模板 (html):
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
看起来 help_texts
仅适用于 username
和 email
等模型字段。对于其他字段,可以在__init__
方法中设置help_text
。
class SignUpForm(UserCreationForm):
class Meta:
model = User
...
help_texts = {
'username': 'Please enter an appropriate human name.',
'email': 'Which office?',
}
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['password1'].help_text = 'Something that doesnt look awful'
self.fields['password2'].help_text = 'Something else'
我不会将配置文件字段添加到 SignUpForm
,而是为配置文件创建一个单独的模型表单
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
...
然后在您的视图和模板中包含这两个表单。
回答 OP 最初对 help_text 被转义的担忧:
可以使用'safe'过滤器,例如...
{% if field.help_text %}
<small style="color: grey">{{ field.help_text|safe }}</small>
{% endif %}
在呈现的模板中提供您要查找的列表。
您可能希望查看标题为 Django template escaping 的 SO post,以了解有关此行为的更多示例以及如何控制它。
在过去的几天里,我一直在尝试使用我创建的用于处理用户注册的表单上的默认值 help_text
来解决一个奇怪的问题。当我看到 html django 正在插入时,我第一次注意到这个问题,因为默认的 help_text
正在被转义。
Screenshot of Issue
不是显示 <ul>
,我提醒你这是 django 包含的密码字段的默认 help_text
,而是显示纯文本。
所以这是我第一次注意到一定是做错了什么。如果默认形式 help_text
被转义并且看起来很糟糕,我显然犯了一个错误。接下来我将解释我为解决此问题所做的工作,然后将概述 model
、form
、view
和 template
以便你们有所了解开始工作。
我在网上找到的第一个解决方案是使用Meta
class,所以我在我的forms.py
下修改了class SignUpForm:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
company = forms.CharField()
city = forms.CharField()
state = forms.CharField()
zip = forms.IntegerField()
address = forms.CharField()
phone = forms.IntegerField()
class Meta:
model = User
# help_text = mark_safe
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
labels = {
'state': 'US States',
'password1': 'passcode1',
'password2': 'passcode2',
'username': 'human person',
'email': 'telegraph',
'city': 'locality',
'phone': "tele",
}
help_texts = {
'password1': 'Something that doesnt look awful',
'password2': 'Something else',
'username': 'Please enter an appropriate human name.',
'email': 'Which office?',
'city': 'What county?',
'phone': 'Please Include Country Code',
}
这就是我开始意识到问题比我想象的要严重的地方。不仅是导致 help_text
被转义的原因,其中一些字段接受我的更改,而另一些则不接受。我扩展默认值 UserCreationForm
的自定义字段(在此示例中 city
和 phone
不显示其新的 label
或 help_text
,而默认字段 username
和 email
都显示其空洞的新 label
和 help_text
。最重要的是 password1
和 password2
字段仍然存在不变。
Screenshot of class Meta result
好吧,那是行不通的。将其硬编码到表单中怎么样?好吧,事实证明这大部分是有效的,但在这个例子中它给我带来了另一个层次的复杂性,并且感觉像是不好的做法。我来解释一下。
因为我的表单扩展了默认的 django UserCreationForm
我实际上并没有在我的 SignUpForm
中设置字段,它们是自动添加的并且我在 class Meta:
中使用它们的字段所以为了硬编码解决这个问题,我必须添加它们。
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.safestring import mark_safe
class SignUpForm(UserCreationForm):
username = forms.CharField(help_text=mark_safe("Please enter an appropriate human name."), label='human name')
email = forms.CharField(widget=forms.EmailInput, help_text=mark_safe('Which office?'), label='telegraph')
password1 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something that doesnt look awful'),
label='Passcode')
password2 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something else'), label='Passcode 2')
company = forms.CharField(help_text=mark_safe("Please enter a company name"))
city = forms.CharField(help_text=mark_safe('What county?'), label='locality')
state = forms.CharField(help_text=mark_safe('Please enter the state'))
zip = forms.IntegerField(help_text=mark_safe('Please enter a zip code.'))
address = forms.CharField(help_text=mark_safe('Please enter an address.'))
phone = forms.IntegerField(help_text=mark_safe('Please include country code.'), label='tele')
class Meta:
model = User
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
所以这个可行,但它确实不切实际且令人担忧,因为我还没有解决根本问题。
硬编码结果的屏幕截图(不能post因为我没有足够的代表,但相信我一切正常)
所以这就把我们带到了现在,我已经尝试了一些其他的东西,但是没有什么比硬编码更接近我想要的东西了,所以我需要找出我犯的潜在错误。
所以这是我正在使用的:
models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
username = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.TextField(max_length=500, blank=True)
city = models.CharField(max_length=100, blank=True)
state = models.CharField(max_length=100, blank=True)
zip = models.CharField(max_length=5, blank=True)
address = models.CharField(max_length=200, blank=True)
phone = models.CharField(max_length=12, blank=True)
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
forms.py(当前硬编码版本):
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.safestring import mark_safe
class SignUpForm(UserCreationForm):
username = forms.CharField(help_text=mark_safe("Please enter an appropriate human name."), label='human name')
email = forms.CharField(widget=forms.EmailInput, help_text=mark_safe('Which office?'), label='telegraph')
password1 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something that doesnt look awful'),
label='Passcode')
password2 = forms.CharField(widget=forms.PasswordInput, help_text=mark_safe('Something else'), label='Passcode 2')
company = forms.CharField(help_text=mark_safe("Please enter a company name"))
city = forms.CharField(help_text=mark_safe('What county?'), label='locality')
state = forms.CharField(help_text=mark_safe('Please enter the state'))
zip = forms.IntegerField(help_text=mark_safe('Please enter a zip code.'))
address = forms.CharField(help_text=mark_safe('Please enter an address.'))
phone = forms.IntegerField(help_text=mark_safe('Please include country code.'), label='tele')
class Meta:
model = User
fields = ('company', 'city', 'state', 'zip', 'address', 'phone', 'username', 'email', 'password1', 'password2')
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from apps.dashboard.forms import SignUpForm
def signup(request):
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.profile.company = form.cleaned_data.get('company')
user.profile.city = form.cleaned_data.get('city')
user.profile.state = form.cleaned_data.get('state')
user.profile.zip = form.cleaned_data.get('zip')
user.profile.address = form.cleaned_data.get('address')
user.profile.phone = form.cleaned_data.get('phone')
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect(main)
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
模板 (html):
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
看起来 help_texts
仅适用于 username
和 email
等模型字段。对于其他字段,可以在__init__
方法中设置help_text
。
class SignUpForm(UserCreationForm):
class Meta:
model = User
...
help_texts = {
'username': 'Please enter an appropriate human name.',
'email': 'Which office?',
}
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['password1'].help_text = 'Something that doesnt look awful'
self.fields['password2'].help_text = 'Something else'
我不会将配置文件字段添加到 SignUpForm
,而是为配置文件创建一个单独的模型表单
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
...
然后在您的视图和模板中包含这两个表单。
回答 OP 最初对 help_text 被转义的担忧:
可以使用'safe'过滤器,例如...
{% if field.help_text %}
<small style="color: grey">{{ field.help_text|safe }}</small>
{% endif %}
在呈现的模板中提供您要查找的列表。
您可能希望查看标题为 Django template escaping 的 SO post,以了解有关此行为的更多示例以及如何控制它。