将字段添加到不在模型中的Django ModelForm

Cyc*_*lic 11 python django django-forms

我的模型看起来像:

class MySchedule(models.Model):
  start_datetime=models.DateTimeField()
  name=models.CharField('Name',max_length=75)
Run Code Online (Sandbox Code Playgroud)

随之而来的是它的ModelForm:

class MyScheduleForm(forms.ModelForm):
  startdate=forms.DateField()
  starthour=forms.ChoiceField(choices=((6,"6am"),(7,"7am"),(8,"8am"),(9,"9am"),(10,"10am"),(11,"11am"),
      (12,"noon"),(13,"1pm"),(14,"2pm"),(15,"3pm"),(16,"4pm"),(17,"5pm"),
      (18,"6pm"
  startminute=forms.ChoiceField(choices=((0,":00"),(15,":15"),(30,":30"),(45,":45")))),(19,"7pm"),(20,"8pm"),(21,"9pm"),(22,"10pm"),(23,"11pm")))

  class Meta:
    model=MySchedule

  def clean(self):
    starttime=time(int(self.cleaned_data.get('starthour')),int(self.cleaned_data.get('startminute')))
    return self.cleaned_data

  try:
    self.instance.start_datetime=datetime.combine(self.cleaned_data.get("startdate"),starttime)

  except TypeError:
    raise forms.ValidationError("There's a problem with your start or end date")
Run Code Online (Sandbox Code Playgroud)

基本上,我试图将模型中的DateTime字段分成3个更容易使用的表单字段 - 日期选择器,小时下拉列表和分钟下拉列表.然后,一旦我获得了三个输入,我将它们重新组合成DateTime并将其保存到模型中.

几个问题:

1)这完全是错误的做法吗?我不想在模型中创建小时,分钟等字段,因为这基本上只是中间数据,所以我想要一种方法将DateTime字段分成子字段.

2)我遇到的困难是当startdate字段为空时 - 似乎永远不会检查非空白,并且当程序期望日期并且获得None时,最终会抛出TypeError.Django在哪里检查空白输入,并提出最终返回到表单的错误?这是我的责任吗?如果是这样,我该怎么做,因为它不评估clean_startdate()因为startdate不在模型中.

3)有没有更好的方法来继承?也许在BetterScheduleForm中继承MyScheduleForm并在那里添加字段?我该怎么做?(我一直在玩它超过一个小时,似乎无法得到它)

谢谢!

[编辑:]关闭返回self.cleaned_data - 最初在复制/粘贴中丢失

Yuj*_*ita 0

1:我不认为这是错误的,因为那里发生了一些非常具体的事情:

  • 具体时间条目(中午,下午5点结束..)
  • 开始分钟以 15 分钟为增量

2:更新:下面的评论说您的字段应该是required=True默认的。确实如此,ValidationError如果该字段留空,您的表格应该会收到一个。

你能发布TypeError你所说的吗?事情发生在clean()街区之外吗?因为如果您没有cleaned_data像示例中那样从 clean 函数返回,那么您的表单将没有任何数据可使用,即使它最初通过不引发任何ValidationErrors.

无论如何,您可以探索clean_每个字段验证的方法。

def clean_startdate(self):  
    if not self.cleaned_data['startdate']:
            raise forms.ValidationError("Must enter a start date")
Run Code Online (Sandbox Code Playgroud)

http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-clean-method

3:你能在这里澄清一下你想用继承来做什么吗?看起来您的字段定义非常特定于此表单,因此它属于MyScheduleForm. 继承是为了重用代码:)

如果您希望将其重用于多个DateTimeField,是的,您可以使用表单继承。您可以定义ModelForm像现在这样的子类,并覆盖父级,Meta如文档中所示,以便在多个模型上使用它: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#形式继承

我还要检查 django 如何执行其 SplitDateTimeWidget (检查源代码): http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.SplitDateTimeWidget

互联网上还有一些其他“第 3 方”分割日期时间小部件也值得一看!