我几乎一整天都在阅读有关forms
和的文档ModelForms
。我设法使用了基本的东西,但现在我真的遇到了麻烦,因为我在文档中没有找到任何关于映射模型字段与非模型字段的提示。那就是我的意思:
我有这个模型:
class Process(models.Model):
key = models.CharField(max_length=32, default="")
name = models.CharField(max_length=30)
path = models.CharField(max_length=215)
author = models.CharField(max_length=100)
canparse = models.NullBooleanField(default=False)
last_exec = models.DateTimeField(null = True)
last_stop = models.DateTimeField(null = True)
last_change = models.DateTimeField(null = True, auto_now=True)
用户要修改的唯一字段是name
和author
。path
是我的Process的配置文件的绝对真实路径。目录是固定的,用户不会关心目录是/home/measure/conf
或/var/whatever
),他们只关心文件名。这就是为什么我想filename
在我的ModelForm
.
我的表格如下所示:
class ProcessForm(MonitorForm):
filename = forms.CharField(max_length=250)
class Meta:
model = Process
fields = ('name', 'filename', 'author')
现在,我想要的是filename
包含存储在其中的文件名Process.path
而不是整个路径,这就是我的意思:
>>> from monitor.forms import ProcessForm
>>> from remusdb.models import Process
>>>
>>> p = Process(name="test1", path="/tmp/config/a.cnf", author="pablo")
>>> f = ProcessForm(instance=p)
>>> print f["filename"].value()
---> here I want to get "a.cnf"
问题是我不知道如何在我打电话后写入a.cnf
该字段。我想过在函数中这样做,但我不确定这是否是一个好地方。我认为此时为时已晚,因为这些字段或多或少是只读的,一旦初始化,您就无法更改它们的值。那么我该怎么做呢?我应该创建一个自定义字段并覆盖吗?filename
ProcessForm(instance=p)
clean
__init__
我从阅读表单字段默认清理中得到了这个想法,并想先测试一下。我不想先覆盖init,我想首先使用to_python
文档中的方法。所以我创建了这个类RemusFilenameField
:
class RemusFilenameField(forms.CharField):
def to_python(self, value):
print "to_python's value is %s" % value
return value.upper()
def clean(self, value):
print "clean's value is %s" % value
return value.upper()
并将filename
线路更改ProcessForm
为
filename = RemusFilenameField(max_length=250)
我添加了打印以查看调用此方法的位置/时间。但是根本不调用这些方法。我怀疑是因为形式没有界限。所以我这样做了:
>>> p = {"name": "test1", "filename": "a.cnf", "author": "pablo"}
>>> f = ProcessForm(p)
>>> f.is_valid()
clean's value is a.cnf
True
>>> print f["filename"].value()
a.cnf
该to_python
方法也没有被调用,我希望看到A.CNF
因为clean
返回不同的东西。
我不知道如何解决这个问题,甚至这是否是一个好主意。我的下一个问题是何时f.save()
执行正确path
的必须filename
从instance
. 我会在clean
方法中这样做还是有更好的选择?
编辑:我想我有一个创建表单的解决方案(我必须阅读整个源代码以识别python2.6/site-packages/django/forms/models.py
用法model_to_dict
:
from django.forms.models import model_to_dict
import os
class ProcessForm(MonitorForm):
filename = RemusFilenameField(max_length=250)
def __init__(self, *args, **kwargs):
super(ProcessForm, self).__init__(*args, **kwargs)
try:
proc = kwargs["instance"]
filename = os.path.basename(proc.path)
self.initial.update({'filename': unicode(filename)})
except:
pass
class Meta:
model = Process
fields = ('name', 'filename', 'author')
它知道有效:) 现在我必须弄清楚如何修复该save()
方法