django 中的表单占位符无法正确显示

Posted

技术标签:

【中文标题】django 中的表单占位符无法正确显示【英文标题】:Form placeholder in django doesn't show properly 【发布时间】:2015-07-10 20:46:24 【问题描述】:

如标题中所述,表单小部件中的占位符属性无法正确显示。它是随机的,有时效果很好,有时我需要刷新浏览器才能显示。 我需要它们,因为我没有在模板中显示字段标签。 无论如何这里是代码:

#FORMS.PY
class RegistrationForm(UserCreationForm):
    first_name = forms.CharField(label=_('First name'), max_length=30)
    last_name = forms.CharField(label=_('Last name'), max_length=30)
    email = forms.EmailField(label=_("Email"), required=True)

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')

    def __init__(self, *args, **kwargs):
        super(RegistrationForm, self).__init__(*args, **kwargs)
        # Set field Label as Placeholder for every field
        for field in self.base_fields.values(): 
            field.widget.attrs["placeholder"] = field.label
        # Set html and CSS attributes to the fields
        self.fields['username'].widget.attrs.update('class':TEXTINPUT_CSS)
        self.fields['email'].widget.attrs.update('class':EMAILINPUT_CSS)
        self.fields['password1'].widget.attrs.update('class':PASSWORDINPUT_CSS)
        ...

顺便说一句,我正在使用 django 开发服务器,问题可能来自服务器速度慢的事实。 任何帮助将不胜感激

编辑:根据要求修改 Views.py 和模板

#views.py
def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            if REGISTER_EMAIL_CONFIRMATION == True:
                # Add email confirmation
                username = form.cleaned_data['username']
                email = form.cleaned_data['email']
                salt = hashlib.sha1(str(random.random()).encode('utf-8')).hexdigest()[:5]            
                activation_key = hashlib.sha1((salt+email).encode('utf-8')).hexdigest()            
                key_expires = datetime.datetime.today() + datetime.timedelta(CONFIRMATION_KEY_EXPIRE_DAYS)
                # Create and save User Profile
                user=User.objects.get(username=username)            
                new_profile = UserProfile(user=user, activation_key=activation_key, key_expires=key_expires)
            new_profile.save()
                # Send email with activation key
                subject_file = 'app_authentication/email_signup_confirm_subject.txt'
                body_file = 'app_authentication/email_signup_confirm_body.html'
                context = 'username':username, 'activation_key':activation_key
                send_email_from_files([email], subject_file, body_file, context)
                return redirect('confirm_email_sent')
            else:
                return redirect('register_success')
    else:
        form = RegistrationForm()
    return render(request, 'registration/register.html', 'form': form, 'title': _('Register'))


#register.html
% block content2 %
<form id="register_form" autocomplete="off" method="post" action="% url 'register' %">
% csrf_token %
    <div class="clearfix">
    % for field in form %
        <div class="form-group">
             field 
            % if form.errors %
            % for error in field.errors %
                <div class="alert alert-error">
                    <strong> error|escape </strong>
                </div>
            % endfor %
            % endif %
        </div>
    % endfor %
        % if form.errors %
        % for error in form.non_field_errors %
            <div class="alert alert-error">
                <strong> error|escape </strong>
            </div>
        % endfor %
        % endif %
    </div>
    <!-- Send Button -->
    <div class="pt-10">
        <button class="submit_btn btn btn-mod btn-medium btn-round btn-full" id="reg-btn" name="submit"> title </button>
    </div>
</form>
% endblock content2 %

截图:

当我启动开发服务器并尝试登录时:

刷新浏览器后,登录页面相同:

@akarilimano:

class LoginForm(AuthenticationForm):
    # username doesn't have label in AuthenticationForm
    username = forms.CharField(label=_("Username"), max_length=254)

    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        # Set field Label as Placeholder for every field
        for field in self.base_fields.values():
            print(field.label)
            field.widget.attrs['placeholder'] = field.label

【问题讨论】:

占位符的输出是什么?到目前为止,这看起来应该可以工作。 我得到了预期的结果(标签用作占位符),但我只得到了 10 次中的 7 次。当它不起作用时,我得到空白表单字段(没有占位符)。我在登录表单中也遇到了同样的问题,代码相同。 @khalilan 这些是登录页面的屏幕,注册页面有同样的问题吗?能否提供登录代码(表单、视图)? @akarilimano :我在两种形式中都有同样的问题。我使用默认的 django 视图和表单进行登录,并在 init 中为占位符添加相同的代码(请检查第一篇文章) 【参考方案1】:

如果您在Meta 中定义了model = User,为什么需要此代码?

first_name = forms.CharField(label=_('First name'), max_length=30)
last_name = forms.CharField(label=_('Last name'), max_length=30)
email = forms.EmailField(label=_("Email"), required=True)

也许他们与模型字段发生冲突?您可以尝试删除非模型表单字段吗?

【讨论】:

我之前用它们来添加占位符,忘记注释掉first_name = forms.CharField(label=_('First name'), max_length=30, widget=forms.TextInput(attrs='placeholder': 'First Name'))我会删除它们并立即检查 当我运行服务器并访问网站并尝试登录或注册时,占位符第一次不显示,它们仅在我刷新后显示。但是一旦他们在那里,他们总是会表现出来,所以这是一种进步。 @KhalilAn 你可以尝试用field.widget.attrs.update('placeholder': field.label) 替换field.widget.attrs["placeholder"] = field.label 吗?或者尝试将for循环移动到__init()__的末尾。 不幸的是,这两个建议都没有奏效,这让我发疯了。我可能会说一些完全愚蠢的话,但它可能与缓存有关,因为第一次表单不显示占位符,并且在我刷新页面后,占位符出现并正常工作,直到服务器重新启动。 @KhalilAncan 你能提供那个表单的视图和模板代码吗?【参考方案2】:

尝试在此处更改base_fields

    for field in self.base_fields.values(): 

fields:

    for field in self.fields.values():

base_fields 字典是为类定义的基本字段集。您可以更改它,但不建议这样做,在您的情况下不需要。

如果你在更改base_fields 后调用super,我猜你的版本会起作用:

def __init__(self, *args, **kwargs):
    for field in self.base_fields.values(): 
        field.widget.attrs["placeholder"] = field.label
    super(RegistrationForm, self).__init__(*args, **kwargs)

【讨论】:

完美运行。非常感谢!【参考方案3】:

尝试将占位符直接定义为小部件属性,例如:

 class RegistrationForm(UserCreationForm):
        first_name = forms.CharField(label=_('First name'), max_length=30, widget=forms.TextInput(attrs="placeholder": "First name"))
        last_name = forms.CharField(label=_('Last name'),max_length=30, widget=forms.TextInput(attrs="placeholder": "Last Name"))
        email = forms.EmailField(label=_("Email"), required=True, widget=forms.TextInput(attrs="placeholder": "Email"))

【讨论】:

我确定您的建议有效,但我正在寻找更干燥的答案。 (+1) @KhalilAn 我想我们只是使用 HTML 占位符属性。

以上是关于django 中的表单占位符无法正确显示的主要内容,如果未能解决你的问题,请参考以下文章

Django CMS 自动显示正确的占位符插件

如何将类、id、占位符属性添加到 django 模型表单中的字段

Django - 如何在作为模型当前字段的模型表单上添加占位符?

django 将占位符文本添加到表单字段

Textarea占位符未显示[重复]

将占位符字段添加到基本的 UserCreation Django 注册表单