在表单中使用SelectDateWidget

2 投票
2 回答
2894 浏览
提问于 2025-04-18 07:42

我现在遇到一个问题,想把SelectDateWidget应用到我Django里的所有日期字段上。我试过在这里这里找到的设置方法。尽管我尝试了这些方法,表单还是显示成默认的日期文本输入框。任何帮助都非常感谢!

Forms.py

from django import forms
from django.forms import ModelForm, DateInput, DateField
from django.forms.extras.widgets import SelectDateWidget
from extra_views import InlineFormSet, CreateWithInlinesView, UpdateWithInlinesView
from extra_views.generic import GenericInlineFormSet
from django.forms.models import inlineformset_factory
from employee_summary.models import Employee, Work_Record, Training_Record, FAA_Certificate

class EmployeeForm(ModelForm):
    class Meta:
        model = Employee
        #This method doesn't seem to work
        red_badge = forms.DateField(widget=extras.SelectDateWidget)

    #This method doesn't seem to work either
    def __init__(self, *args, **kwargs):
        super(EmployeeForm, self).__init__(*args, **kwargs)
        this_year = datetime.date.today().year
        years = range(this_year-100, this_year+1)
        years.reverse()
        self.fields["hire_date"].widget = SelectDateWidget(years=years)

class WorkRecordFormSet(InlineFormSet):
    model = Work_Record
    prefix = "work_record"
    extra = 1


class TrainingRecordFormSet(InlineFormSet):
    model = Training_Record
    prefix = "training_record"
    extra = 1

class FAACertificateFormSet(InlineFormSet):
    model = FAA_Certificate
    prefix = "faa_certificate"
    extra = 1

模板 (Create.html)

{% extends "base.html" %}
{% load sekizai_tags formset_tags %}
{% block base_content %}

<link rel="stylesheet" href="/media/themes/txt/css/employee_summary/report.css" />

{{ formset.media }}

<div id="main-wrapper">
<div class="strongborder">
    <div id="main" class="container boldtext">
        <form id="myForm" method="post" class="12u">
            {% csrf_token %}
            {% for field in form %}
                <div class="row">
                    <div class="2u">
                        {{ field.label_tag }}:
                    </div>
                    <div class="10u">
                        {{ field }}
                        {{ field.errors }}
                    </div>
                </div>
            {% endfor %}

        {% for formset in inlines %}

            <div id="formset_{{ forloop.counter0 }}" data-formset-prefix="{{ formset.prefix }}">
                {{ formset.management_form }}
                    <!-- New forms will be inserted in here -->
                    <div data-formset-body>
                        {% for form in formset %}
                            <br>
                            <br>
                            <h1>{{ form.instance.form_name }}</h1>
                            <div data-formset-form>
                                {% for field in form %}
                                    <div class="row">
                                        {% if field.label != "Employee" and field.label != "Id" and field.label != "Delete" %}
                                            <label class="2u">{{ field.label }}:</label> 
                                            <div class="10u">{{ field }}</div>
                                            {{ field.errors }}
                                        {% endif %}
                                    </div>
                                {% endfor %}
                            </div>
                        {% endfor %}
                    </div>


                <!-- The empty form template. By wrapping this in a <script> tag, the
                __prefix__ placeholder can easily be replaced in both attributes and
                any scripts -->
                <script type="form-template" data-formset-empty-form>
                    {% escapescript %}
                        <br>
                        <br>
                        <div data-formset-form>
                            {% for field in formset.empty_form %}
                                <div class="row">
                                    {% if field.label != "Employee" and field.label != "Id" and field.label != "Delete" %}
                                        <label class="2u">{{ field.label }}:</label> 
                                        <div class="10u">{{ field }} <br> {{ field.errors }}</div>
                                    {% endif %}
                                </div>
                            {% endfor %}

                        </div>

                    {% endescapescript %}
                </script>

                <!-- This button will add a new form when clicked -->
                <button type="button" class="text-green" data-formset-add><i class="fa fa-plus-circle"></i> Add another</button>

                <script>jQuery(function($) {
                    $("#formset_{{ forloop.counter0 }}").formset({
                        animateForms: true
                    });
                });</script>

            </div>

        {% endfor %}

        <br>
        <br>

        <div class="row 12u">
            <input type="submit" value="Save New Employee">    
        </div>

        </form>
    </div>
</div>
</div>


{% endblock %}

2 个回答

1

你可以在 ModelForm 中使用 widgets 字典。相关的 Django 文档可以在 这里 找到,里面提到:

要为某个字段指定一个自定义的控件,可以使用内部 Meta 类的 widgets 属性。这个属性应该是一个字典,用来将字段名映射到控件类或实例。

在你的情况下,这意味着:

from django.forms import widgets  

class EmployeeForm(ModelForm):
    class Meta:
        model = Employee
        fields = ['red_badge']
        widgets = {'red_badge': widgets.SelectDateWidget()}
1

我在一个表单里有两个字段,使用了 SelectDateWidget,就像这样:

import datetime

from django import forms
from django.forms.extras.widgets import SelectDateWidget

from consoles.models import Runner
from generic.forms.widgets import SelectTimeWidget


class RunnerDetailsForm(forms.ModelForm):

    best_time = forms.TimeField(
        widget=SelectTimeWidget(dashed=True, race_time=True)
    )
    years_to_display = range(datetime.datetime.now().year - 100,
                             datetime.datetime.now().year)
    dob = forms.DateField(
        widget=SelectDateWidget(years=years_to_display)
    )
    predicted_time = forms.TimeField(
        widget=SelectTimeWidget(dashed=True, race_time=True)
    )

    class Meta:
        model = Runner

只需要在表单里定义你的字段,然后给每个字段添加 SelectDateWidget 就可以了 :)

撰写回答