【问题标题】:Editing default fields' help_text for form in Django (1.11)在 Django (1.11) 中为表单编辑默认字段的 help_text
【发布时间】:2017-12-18 16:40:33
【问题描述】:

在过去的几天里,我一直在尝试使用我创建的用于处理用户注册的表单上的默认 help_text 来解决一个奇怪的问题。当我看到 html django 正在插入时,我首先注意到了这个问题,因为默认的 help_text 正在被转义。

Screenshot of Issue

不是显示<ul>,我提醒你的是django为密码字段包含的默认help_text,而是显示纯文本。

所以这是我第一次注意到一定做错了什么。如果默认表单help_text 被转义并且看起来很糟糕,那么我显然犯了一个错误。接下来,我将解释我为解决此问题所做的工作,然后概述modelformviewtemplate,以便你们有一些工作要做。

我在网上找到的第一个解决方案是使用Meta 类,所以我在我正在修改的class SignUpForm: 下的forms.py 中使用了。

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 的自定义字段(在此示例中,cityphone 不显示它们的新 labelhelp_text,而默认字段 usernameemail 两者显示他们的新 labelhelp_text。最重要的是,password1password2 字段保持不变。

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')

所以这个可行,但它确实不切实际且令人担忧,因为我还没有解决根本问题。

硬编码结果的屏幕截图(无法发布,因为我没有足够的代表,但相信我一切正常)

所以到现在,我尝试了其他一些方法,但没有什么比硬编码更接近我想要的,所以我需要找出我所犯的潜在错误。

这就是我正在使用的:

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>

【问题讨论】:

  • Rob Simpson 的回答对我来说似乎是正确的。无论如何,它是为我解决它的那个。

标签: django django-models django-forms django-views django-users


【解决方案1】:

回答 OP 最初对 help_text 被转义的担忧:

可以使用“安全”过滤器,例如...

    {% if field.help_text %}
      <small style="color: grey">{{ field.help_text|safe }}</small>
    {% endif %}

在呈现的模板中提供您要查找的列表。

您可能希望查看标题为 Django template escaping 的 SO 帖子,了解有关此行为的更多示例以及如何控制它。

【讨论】:

  • 对我来说似乎是正确的答案。非常感谢,这对我也有帮助。
  • 谢谢!如果你这么认为,那么你可以评论 OP 吗?我的声望太低了……
【解决方案2】:

看起来help_texts 仅适用于usernameemail 等模型字段。对于其他字段,您可以在__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
        ...

然后在您的视图和模板中包含这两个表单。

【讨论】:

  • 为什么不包括这些字段?这部分是更大的东西吗?我收到此错误django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form SignUpForm needs updating.
  • 我省略了这些字段,因为它们与答案没有直接关系。您应该将它们包含在您的表单中。
  • 非常好,这样行得通。所以我必须一次做那一行?标签一行,help_text 一行? self.fields['password1'].help_text = 'Something that doesnt look awful' self.fields['password1'].label = 'Passcode'
  • 谢谢!我之前尝试过__init__ 方法,但您的方法效果更好。我很感激。
  • @anjanesh 文档说help_texts 应该可以工作,所以如果它不适合您,那么您需要提出一个新问题并显示您的代码。这个问题已经 4 年了,所以我认为你不会在 cmets 中得到帮助。
猜你喜欢
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 2018-03-25
  • 2018-01-29
  • 2015-02-28
  • 2011-02-22
相关资源
最近更新 更多