forms
과 ModelForms
에 관한 문서를 거의 하루 종일 보냈습니다. 나는 기본적인 것들을 사용할 수 있었지만 모델 필드를 모델이 아닌 필드와 매핑하는 것에 대한 설명서에서 힌트를 찾지 못해서 현재 정말로 문제가 있습니다. 즉 I의 의미는 다음과 같습니다ModelForm의 비 모델 필드로 모델 필드 매핑하기
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
은 내 프로세스의 구성 파일의 절대 실제 경로입니다. 디렉토리가 고정되어 있고 사용자가 디렉토리가 /home/measure/conf
또는 /var/whatever
인지 여부는 신경 쓰지 않습니다. 파일 이름 만 신경 써야합니다. 그래서 ModelForm
에 filename
필드가 필요합니다. 같은
내 양식을 보이는 :
이제class ProcessForm(MonitorForm):
filename = forms.CharField(max_length=250)
class Meta:
model = Process
fields = ('name', 'filename', 'author')
, 내가 원하는 것은 filename
이 Process.path
과 전체가 아닌 경로 저장 파일 이름을 포함, 즉 I의 의미는 다음과 같습니다
>>> 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"
문제는 내가 로 전화하면 을 filename
필드에 쓰는 방법을 모른다는 것입니다. 나는 clean
함수에서 그것을 수행하는 것에 대해 생각했지만 이것이 좋은 곳인지 전혀 확신 할 수 없습니다. 필드가 다소 읽기 전용이기 때문에이 시점에서 너무 늦을 것이라고 가정합니다. 일단 initilaized되면 값을 변경할 수 없습니다. 어떻게해야합니까? 사용자 정의 필드를 만들고 __init__
을 재정의해야합니까?
나는이 아이디어를 form field default cleaning에서 읽었으며 첫 번째 테스트를 원했습니다. 나는 init을 우선 쓰지 않으려 고하고 나는 설명서 에서처럼 to_python
메쏘드로 먼저 놀았다고 생각했다. 나는이 방법이 전화를받을 때/위치를 확인하기 위해 지문을 추가
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 = RemusFilenameField(max_length=250)
에 ProcessForm
에 filename
라인을 변경 : 그래서 클래스 RemusFilenameField
를 만들었습니다. 그러나이 방법은 전혀 호출되지 않습니다. 형태가 한정되어 있지 않기 때문에 나는 의심한다. 그래서 대신에 이런 짓을 :
>>> 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
방법은라고도 점점되지 않고 나는 clean
다른 무언가를 반환하기 때문에 A.CNF
를 볼 것으로 예상.
이 문제를 해결하는 방법과 이것이 전혀 좋은 아이디어인지 전혀 알 수 없습니다. 다음 번 문제는 f.save()
이 실행될 때 path
이 filename
에서 생성되고 instance
에 저장되어야합니다. 나는 이것을 clean
방법으로 할 것인가 아니면 더 좋은 선택이 될 것인가?
편집가 :
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')
그것은이 작품이 지금 :) 알고 : 나는 양식의 창조를위한 해결책을 가지고 생각 (나는 python2.6/site-packages/django/forms/models.py
에 model_to_dict
사용을 식별하기 위해 전체 소스 코드를 읽을 수 있었다 save()
메서드를 수정하는 방법을 찾아야합니다.
감사합니다. 이는 의미가 있으며 "로드"부분보다 더 쉽습니다. 'django.forms.models'의 소스 코드를 읽은 후에는 의미가 있습니다. – Pablo