Django: django 동적 정의 폼 (form) 을 어떻게 사용 하 는 지
최근 의 프로젝트 개발 은 이러한 데이터 구 조 를 사용 했다. 주로 설 비 를 관리 하 러 왔 다.
다음은 제 가 간단 한 구 조 를 열거 하 겠 습 니 다. 더 이상 필요 하지 않 습 니 다. 나머지 는 불필요 하거나 금상첨화 라 고 할 수 있 습 니 다. 설비 분류 (설비 의 큰 분류 에 해당 하 는) 의 데이터 구조 입 니 다.
class Category(models.Model):
name = models.CharField(max_length=40)
구체 적 인 장치 의 데이터 구조:
class Equipment(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, related_name="cg_equip_list")
장치 매개 변수의 데이터 구조:
class Characteristic(models.Model):
category = models.ForeignKey(Category, related_name="eq_characteristics")
name = models.CharField(max_length=40)
장치 매개 변수의 값 데이터 구조:
class CharacteristicValue(models.Model):
equipment = models.ForeignKey(Equipment, related_name="eq_characteristic_values")
characteristic = models.ForeignKey(Characteristic, related_name="eq_key_values")
value = models.CharField(max_length=100)
많은 사람들 이 장치 의 매개 변수 값 을 장치 의 데이터 구조 에 직접 정의 하지 않 느 냐 고 물 을 것 이다.제 대답 은 이렇게 하면 더 많은 장 치 를 스스로 정의 할 수 있 습 니 다. 모든 장치 의 매개 변 수 는 다 릅 니 다. 예 를 들 어 컴퓨터 의 매개 변 수 는 기본적으로 CPU 주파수, 메모리 크기, 하 드 디스크 크기, 디 스 플레이 유형, 디 스 플레이 크기 등 입 니 다.
프린터 의 인 자 는 다음 과 같 습 니 다. 최대 인쇄 용지 폭, 프린터 종류 등.
이렇게 두 가지 서로 다른 매개 변 수 를 가 진 장 치 는 어떻게 그들의 데 이 터 를 데이터베이스 에 저장 해 야 합 니까?방금 위의 질문 에 따 르 면, 우 리 는 2 개의 표, 컴퓨터 표 와 프린터 표를 만들어 야 하 며, 각각 해당 하 는 매개 변 수 를 열 에 포함 시 켜 야 합 니 다. 그러면 카메라 와 같은 장치 가 더 많 으 면, 우 리 는 데이터 표를 한 장 더 만들어 야 하 며, 데이터 베 이 스 를 유지 하 는 데 지 쳐 야 합 니 다.
그러나 매개 변수 와 설비 의 분리 에 따라 매개 변수 표 의 형식 으로 각종 설비 의 매개 변 수 를 정의 하고 외부 키 로 설비 분류 표 에 연결 한 다음 에 구체 적 인 설비 의 각종 매개 변수의 값 을 매개 변수 값 표 에 넣 으 면 각 설비 의 매개 변 수 를 저장 할 수 있다.
매개 변수 값 의 데이터 시트 에서 하나의 매개 변 수 는 어느 장치 에 속 하 는 지, 주로 장치 의 id 와 매개 변수의 id 에 따라 확정 합 니 다. 이러한 표 구 조 는 상대 적 으로 통용 되 습 니 다.
비교적 번 거 로 운 것 은 장 치 를 추가 할 때 해당 하 는 매개 변수 값 을 증가 해 야 한 다 는 것 이다. 그 매개 변 수 는 장치 표 에 있 지 않 기 때문에 매개 변수 표를 통 해 조회 해 야 한다. 매개 변수 표 에서 매개 변수의 장치 분류 id = 구체 적 인 장치 의 소속 장치 분류 id 줄 은 바로 이 장치 가 가지 고 있 는 매개 변수 이다.
예 를 들 면:
장치 분류 표 의 데이터: id name1 데스크 톱 컴퓨터 프린터
매개 변 수 는 매개 변수 표 에 다음 과 같은 몇 줄 의 데 이 터 를 저장 합 니 다: id name category 1 CPU 주파수 1 2 MAC 주소 1 3 메모리 크기 1 4 모니터 크기 모니터 종류 16 하드디스크 크기 1 7 최대 인쇄 폭 2
데스크 톱 컴퓨터 에는 6 개의 인자 가 있 고 프린터 에는 1 개의 인자 가 있다 는 것 을 한눈 에 알 수 있다.
제2 절 해결 방안 의 선택
데이터 구조 가 명확 해 졌 습 니 다. 현재 의 문 제 는 이 매개 변수의 값 을 어떻게 입력 하 느 냐 하 는 것 입 니 다.어려움 은 모든 장치 의 매개 변수의 개수 가 확실 하지 않다 는 것 이다. 따라서 form 을 정의 할 때 우 리 는 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 고정 적 으로 증가 하고 감소 하 는 field
여기 서 제 생각 은 매개 변수 개수 가 데이터베이스 에 저 장 된 이상 데이터 베 이 스 를 조회 하여 동적 으로 생 성 해 야 한 다 는 것 입 니 다. 그렇다면 django 를 사용 하려 면 어떤 구체 적 인 방법 을 사용 해 야 합 니까?
나 자신 은 많은 방법 을 시험 해 보 았 고, 또한 디 버 깅 과정 에서 천천히 이 문 제 를 해결 하 는 방법 을 찾 았 다.
과정 은 다음 과 같 습 니 다. 제 가 생각 하기 시작 한 해결 방안 은 다음 과 같 습 니 다. 1. ajax 를 사용 하여 동적 으로 form 2 를 생 성 합 니 다. admin 의 방법 을 사용 하여 inline 의 방법 으로 장 치 를 추가 하 는 동시에 몇 개의 인 자 를 추가 합 니 다. formset 를 사용 하여 4. formtools 의 formwizard (폼 마법사) 를 사용 하여 만 듭 니 다.
문제 의 곤경 은 주로 매개 변수 값 의 표 에 두 개의 외부 키 가 있 기 때문에 어떻게 해 야 할 지 확실 하지 않다. 앞의 세 가지 방법 을 나 는 단지 시험 해 보 았 을 뿐 하루 이틀 동안 디 버 깅 을 하고 포기 했다. 주요 원인 은 1. ajax 나 는 아직 잘 모 르 기 때문에 그것 을 잘 사용 하려 면 관련 된 자바 script 라 이브 러 리 를 배 워 야 한다. 당분간 잘 하지 못 할 것 이다. 2. admin 중의 inline 은 데이터 model 을 대상 으로 하 는 것 이다.증가 하 는 매개 변수 값 도 같 습 니 다. 예 를 들 어 6 개의 CPU 매개 변수 로 증가 할 수 있 습 니 다. 또한 admin 에 사 용 된 것 입 니 다. 자신 이 사용 하 는 것 도 귀 찮 습 니 다. 3. formset 의 form 도 같은 데이터 모델 을 요구 하지만 매개 변수 값 표 에서 2 개의 외부 키 가 높 은 당신 은 formset 를 사용 할 수 없습니다.formset 는 간단 한 데이터 구조 에서 데 이 터 를 입력 하 는 데 사 용 됩 니 다. formset 는 하나의 함수 가 add 입 니 다.fields, 이 함 수 는 비교적 유용 하지만 form 에는 이 함수 가 없습니다. 원 리 를 이해 하면 간단 합 니 다. form [field name] = forms. CharField () 와 같은 것 은 하나의 form 인 스 턴 스 에 field 를 추가 할 수 있 습 니 다. 저 는 formset 가 문 제 를 해결 할 수 있다 고 생각 합 니 다. 그러나 전 제 는 formset 를 구성 하기 전에 formset 에 몇 개의 매개 변수 값 이 있 는 form 이 안에 있 는 지 미리 알 아야 합 니 다.(특정한 분 류 된 장치 에 몇 개의 매개 변수 가 있 는 지 알 아야 한다. 예 를 들 어 formset 에서 몇 개의 form, CharacteristicValue 의 form 을 구축 하고 모든 form 은 서로 다른 매개 변 수 를 사용 하여 initial 을 초기 화 하 는 것 이다). 한 페이지 에서 먼저 장치 의 form 을 추가 합 니 다. 장치 의 매개 변수 개 수 는 고정 되 어 있 지 않 기 때문에 몇 개의 매개 변수 값 폼 을 포함 하 는 formset 를 동적 으로 증가 시 켜 야 합 니 다. 그러면 장치 의 매개 변 수 를 선택 할 수 있 습 니 다. formset 는 고정 개수 의 form 을 사용 하 는 데 비교적 적 용 됩 니 다. 그래서 formset 를 사용 하 는 데 어려움 을 주 었 습 니 다. 이런 방식 을 사용 하려 면 최종 적 으로 ajax 를 사용 하여 루트 를 사용 해 야 합 니 다.사용자 가 장치 형식 을 선택 할 때 동적 생 성 formset. formset 는 view 에서 초기 화 해 야 합 니 다.
그래서 이런 방식 을 나 는 채택 하지 않 았 다.
저 는 폼 가이드 방식 을 사 용 했 습 니 다. jango 의 contrib 에서 formtools 를 제 공 했 습 니 다. 사용 해 봐 야 좋 을 것 같 습 니 다. 저 는 영어 문 서 를 보면 서 조금씩 배 워 서 사용 하 는 것 이 정말 편리 합 니 다. 하지만 위의 4 가지 해결 방안 의 실현 과정 은 매우 어 려 웠 습 니 다. 저 는 3 일 만 에 실 마 리 를 잡 았 습 니 다.
제3 절 구체 적 인 실현
django 에서 폼 마법사 가 사용 하기 쉬 워 요.
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.forms.formsets import BaseFormSet
from django.forms.fields import FileField
from django.forms.util import ValidationError
from django.shortcuts import render_to_response
from django.contrib.formtools.wizard import FormWizard
from ddtcms.office.equipment.models import Equipment,Characteristic,CharacteristicValue
class EquipmentForm(forms.ModelForm):
class Meta:
model = Equipment
class CharacteristicValueForm(forms.Form):
def clean(self):
a=self.fields
s=self.data
self.cleaned_data = {}
# for django forms.py full_clean
for name, field in self.fields.items():
# value_from_datadict() gets the data from the data dictionaries.
# Each widget type knows how to retrieve its own data, because some
# widgets split data over several HTML fields.
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.initial.get(name, field.initial)
value = field.clean(value, initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError, e:
self._errors[name] = self.error_class(e.messages)
if name in self.cleaned_data:
del self.cleaned_data[name]
#cl=self.cleaned_data
#debug()<<< , cl , self.cleaned_data , return ,
return self.cleaned_data
class EquipmentCreateWizard(FormWizard):
def done(self, request, form_list):
return render_to_response('equipment/done.html',
{
'form_data': [form.cleaned_data for form in form_list],
})
def get_form(self, step, data=None):
"Helper method that returns the Form instance for the given step."
form = self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None))
if step == 1:
if data:
cg = data.get('0-category', 1)
cs = Characteristic.objects.all().filter(category__id=cg)
for c in cs:
form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name)
g=form.fields
#debug()
return form
# wizard.py .
def render(self, form, request, step, context=None):
"Renders the given Form object, returning an HttpResponse."
old_data = request.POST
prev_fields = []
if old_data:
hidden = forms.HiddenInput()
# Collect all data from previous steps and render it as HTML hidden fields.
for i in range(step):
old_form = self.get_form(i, old_data)
hash_name = 'hash_%s' % i
prev_fields.extend([bf.as_hidden() for bf in old_form])
prev_fields.append(hidden.render(hash_name, old_data.get(hash_name, self.security_hash(request, old_form))))
if step == 1:
cg = old_data.get('0-category', 1)
cs = Characteristic.objects.all().filter(category__id=cg)
for c in cs:
form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name)
g=form.fields
#debug()
if step == 2:
debug()
return super(EquipmentCreateWizard, self).render(form, request, step, context=None)
def get_template(self, step):
return 'equipment/wizard_%s.html' % step
Equipment Create Wizard 도 views. py 에 넣 을 수 있 고 좀 더 합 리 적 이 라 고 생각 합 니 다. Equipment Create Wizard 에서 process step 함 수 를 수정 해 보 았 지만 정확 한 결 과 를 얻 지 못 했 습 니 다. 나중에 get form 을 수정 하 였 습 니 다. 모두 django 의 formtools 의 wizard. py 에서 복사 하여 수정 하려 고 했 습 니 다. get form 의 수정 도 정확 한 결 과 를 얻 지 못 했 습 니 다. 나중에 ren 을 수정 하 였 습 니 다.der 함수, 두 번 째 단계 에서 저 는 동적 매개 변수 개 수 를 보 여 주 었 습 니 다. 그러나 마지막 에 done 을 끝 낸 부분 에서 얻 은 formdata 에서 두 번 째 form 은 데이터 가 없고 빈 {} 입 니 다. 그래서 저 는 get form 함 수 를 다시 수정 하 였 습 니 다. 두 번 째 단계 인지 아 닌 지 판단 한 다음 에 두 번 째 form 동태 에 몇 개의 field 를 추가 하 는 것 이 아 닙 니 다.
if step == 1:
cg = old_data.get('0-category', 1)
cs = Characteristic.objects.all().filter(category__id=cg)
for c in cs:
form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name)
g=form.fields
#debug()
이 코드 는 get form 과 render 에 있 습 니 다. 모두 두 번 째 단계 인지 아 닌 지 를 판단 한 다음 에 첫 번 째 단계 에서 선택 한 장치 의 분류 에 따라 구체 적 인 분 류 를 조회 한 다음 에 분류 에 따라 이 분 류 된 장치 에 어떤 매개 변수 가 있 는 지 를 얻 은 다음 에 매개 변수 개수 에 따라 form 의 매개 변수 field 의 개 수 를 수정 합 니 다. 'Characteristic -' + str (c. id)나중에 데 이 터 를 저장 할 때 split 이 문자열 은 매개 변수의 id 를 얻 고 매개 변수 값 표 에 Characteristic - 1, Characteristic - 2... 의 value 를 저장 합 니 다.
g=form.fields#debug()
매개 변수 field 가 몇 개 있 는 지, 수정 에 성 공 했 는 지 정지점 에서 볼 수 있 습 니 다.
=========================
from django.conf.urls.defaults import *
from ddtcms.office.equipment.forms import EquipmentForm,CharacteristicValueForm,EquipmentCreateWizard
urlpatterns = patterns('ddtcms.office.equipment.views',
url(r'^$', 'index', name="equipment_index"),
url(r'^add/$', 'equipment_create', name="equipment_create"),
url(r'^add-by-wizard/$',EquipmentCreateWizard([EquipmentForm, CharacteristicValueForm]), name="equipment_create_by_wizard"), )
,csdnbolg $ , , .
==========================wizard_0.html
{% block content %}
<h2> / </h2>
<p> {{ step }} , {{ step_count }} .</p>
<p> </p>
<form method="POST" action="">{% csrf_token %}
<table>
{{ form }}
</table>
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
{{ previous_fields|safe }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
===================wizard_1.html
{% block content %}
<h2> / </h2>
<p> {{ step }} , {{ step_count }} .</p>
<p> , , .</p>
<form method="POST" action="">{% csrf_token %}
<table>
{{ form }}
</table>
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
{{ previous_fields|safe }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
====================done.html
{% block content %}
<h2> / </h2>
<p> .</p>
{{form_data}}
{% endblock %}
============
또한 다른 form 으로 formwizard 를 실현 할 수 있 습 니 다. 바로 첫 번 째 form 1 입 니 다. 주로 사용자 가 장치 의 분 류 를 선택 하도록 합 니 다. form 2 는 앞의 것 에 따라 동적 으로 매개 변 수 를 생 성 하 는 폼 입 니 다. 원 리 는 같 습 니 다.
그리고 view 2 개 를 써 서 formwizard 를 모 의 하 는 것 입 니 다. 첫 번 째 view 는 장 치 를 추가 하고 두 번 째 view 는 장치 id 라 는 매개 변 수 를 가 져 오 면 장치 의 인 자 를 효과적으로 증가 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.