【问题标题】:Change <input> Types and Attributes for a Form Used in a CreateView and UpdateView更改 CreateView 和 UpdateView 中使用的表单的 <input> 类型和属性
【发布时间】:2013-09-08 03:20:56
【问题描述】:

我正在尝试使用 Django 1.4.6 项目来跟踪销售线索。我希望它对移动设备友好,所以我使用 Twitter Bootstrap(仍然是 2.3.2 版)和django-crispy-forms。根据this article,电子邮件字段的最佳方式是&lt;input type="email" autocapitalize="off" autocorrect="off"&gt;,日期字段的最佳方式是&lt;input type="date"&gt;。默认情况下,这些属性都没有在 Django 中实现,我想知道如何最好地实现它们。以下是相关代码(简化):

models.py

from django.db import models


class Lead(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(blank=True, null=True)
    initial_contact_date = models.DateField()

    class Meta:
        ordering = ('name',)

    def __unicode__(self):
        return self.name

views.py

from django.core.urlresolvers import reverse
from django.views.generic import CreateView, ListView, UpdateView
from .models import Lead


class LeadAdd(CreateView):
    model = Lead

    def get_context_data(self, **kwargs):
        context = super(LeadAdd, self).get_context_data(**kwargs)
        context['title'] = 'Add a Lead'
        return context

    def get_success_url(self):
        return reverse('lead_list')


class LeadEdit(LeadAdd, UpdateView):
    def get_context_data(self, **kwargs):
        context = super(LeadEdit, self).get_context_data(**kwargs)
        context['title'] = 'Edit a Lead'
        return context


class LeadList(ListView):
    model = Lead

urls.py

from django.conf.urls import patterns, url
from .views import *


urlpatterns = patterns('',
    url(r'^$', view=LeadList.as_view(), name='lead_list'),
    url(r'^add/$', view=LeadAdd.as_view(), name='lead_add'),
    url(r'^edit/(?P<pk>[\d]+)/$', view=LeadEdit.as_view(), name='lead_edit'),
)

lead_form.html

{% extends 'base.html' %}

{% load crispy_forms_tags %}

{% block content %}
    <div class="page-header">
        <h1>{{ title }}</h1>
    </div>

    <form action="." method="post" class="form-horizontal">
        {% csrf_token %}

        {{ form|crispy}}

        <div class="form-actions">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </form>
{% endblock content %}

【问题讨论】:

    标签: django django-crispy-forms


    【解决方案1】:

    使用字段模板执行此操作 (see the docs on Field):

    Field('email', template="custom-email.html")
    

    或者创建一个自定义小部件。您可以使用abstract class,但现有的预定义小部件之一应该可以工作:

    # widgets.py
    from django.forms.widgets import TextInput
    
    class EmailInput(TextInput):
        input_type = 'email'
    

    所以在你看来它可能是这样的:

    class LeadAdd(CreateView):
        model = Lead
        form_class = LeadAddForm
        ...
    

    然后该 LeadAddForm 类将定义您的自定义小部件:

    from . import widgets
    
    LeadAddForm(forms.Form):
        email = forms.CharField(
            ...
            widget = widgets.EmailInput,
            ...
        )
    

    或者您可以在 init 中设置小部件:

    class LeadAddForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(LeadAddForm, self).__init__(*args, **kwargs)
    
            self.fields['email'].widget = widgets.EmailInput()
    

    您应该能够使用清晰的表单配置设置额外的属性(autocapitalize="off" autocorrect="off"):

    Field('email', autocapitalize="off", autocorrect="off")
    

    【讨论】:

      【解决方案2】:

      更简单的选择:

      forms.py:

      class LeadForm(forms.ModelForm):
          class Meta:
              model = Lead
      
          def __init__(self, *args, **kwargs):
              super(LeadForm, self).__init__(*args, **kwargs)
              self.helper = FormHelper()
              self.helper.form_class = 'form-horizontal'
              self.helper.layout = Layout(
                   Fieldset('Enter the following information',
                            'name',
                            Field('email', type="email",
                                           autocapitalize="off",
                                           autocorrect="off"),
                            Field('initial_contact_date', type="date")),
                   FormActions(
                      Submit('save', 'Create Lead'),
                      Button('cancel', 'Cancel')
                  )
              )
      

      在你的views.py:

      class LeadAdd(CreateView):
          model = Lead
          success_url = reverse('lead_list')
          form_class = LeadForm
      
          def get_context_data(self, **kwargs):
              context = super(LeadAdd, self).get_context_data(**kwargs)
              context['title'] = 'Add a Lead'
              return context
      
      class LeadEdit(LeadAdd, UpdateView):
          def get_context_data(self, **kwargs):
              context = super(LeadEdit, self).get_context_data(**kwargs)
              context['title'] = 'Edit a Lead'
              return context
      

      在您的模板中:

      {% extends 'base.html' %}
      
      {% load crispy_forms_tags %}
      
      {% block content %}
          <div class="page-header">
              <h1>{{ title }}</h1>
          </div>
      
              {% crispy form %}
      
      {% endblock content %}
      

      【讨论】:

        猜你喜欢
        • 2015-06-25
        • 2015-03-08
        • 2016-03-18
        • 1970-01-01
        • 2013-03-22
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多