다음은 내가 한 일입니다.
정보를 키 값 쌍으로 저장 한 모델이 있었기 때문에 모델에 ModelForm을 빌드해야했지만 ModelForm은 키 - 값 쌍을 필드로 표시해야합니다 (예 : 행을 열로 피벗). 기본적으로 모델의 get()
메서드는 항상 자체 모델 인스턴스를 반환하므로 사용자 지정 모델을 사용해야했습니다. 여기 내 키 - 값 쌍 모델이 어떻게 생겼는지입니다 :
class SettingManager(models.Manager):
def get(self, *args, **kwargs):
from modules.customer.proxies import *
from modules.customer.models import *
object = type('DomainSettings', (SettingProxy,), {'__module__' : 'modules.customer'})()
for pair in self.filter(*args, **kwargs): setattr(object, pair.name, pair.value)
setattr(object, 'domain', Domain.objects.get(id=int(kwargs['domain__exact'])))
return object
이 관리자는이 추상 모델의 인스턴스를 인스턴스화합니다 :
class Setting(models.Model):
domain = models.ForeignKey(Domain)
name = models.CharField(null=False, max_length=255)
value = models.CharField(null=False, max_length=255)
objects = SettingManager()
내가
get()
메소드를 오버라이드 (override)이에서 사용자 정의 관리자를 건설했다. 이 프록시는 내 모델에서 키 - 값 쌍으로 내 ModelFom의 표시 및 저장을 원하는 모든 필드가
class SettingProxy(models.Model):
domain = models.ForeignKey(Domain, null=False, verbose_name="Domain")
theme = models.CharField(null=False, default='mytheme', max_length=16)
message = models.CharField(null=False, default='Waddup', max_length=64)
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super(SettingProxy, self).__init__(*args, **kwargs)
for field in self._meta.fields:
if isinstance(field, models.AutoField):
del field
def save(self, *args, **kwargs):
with transaction.commit_on_success():
Setting.objects.filter(domain=self.domain).delete()
for field in self._meta.fields:
if isinstance(field, models.ForeignKey) or isinstance(field, models.AutoField):
continue
else:
print field.name + ': ' + field.value_to_string(self)
Setting.objects.create(domain=self.domain,
name=field.name, value=field.value_to_string(self)
)
(장고 오류를 포기하지 않도록 추상 모델은 테이블이 없습니다). 이제 더 많은 필드를 추가해야하는 경우이 추상 모델을 수정하고 실제 모델 자체를 편집 할 필요가 없습니다. 이제 모델이 생겼으므로 ModelForm을 간단히 빌드 할 수 있습니다.
class SettingsForm(forms.ModelForm):
class Meta:
model = SettingProxy
exclude = ('domain',)
def save(self, domain, *args, **kwargs):
print self.cleaned_data
commit = kwargs.get('commit', True)
kwargs['commit'] = False
setting = super(SettingsForm, self).save(*args, **kwargs)
setting.domain = domain
if commit:
setting.save()
return setting
이 정보가 도움이되기를 바랍니다. 이 점을 이해하려면 API 문서를 통해 많은 파기가 필요했습니다.