django1/django/newforms/models.py

76 lines
2.7 KiB
Python

"""
Helper functions for creating Form classes from Django models
and database field objects.
"""
from forms import BaseForm, DeclarativeFieldsMetaclass, SortedDictFromList
__all__ = ('form_for_model', 'form_for_instance', 'form_for_fields')
def create(self, save=True):
"""
Creates and returns model instance according to self.clean_data.
This method is created for any form_for_model Form.
"""
if self.errors:
raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name)
obj = self._model(**self.clean_data)
if save:
obj.save()
return obj
def make_apply_changes(opts, instance):
"Returns the apply_changes() method for a form_for_instance Form."
from django.db import models
def apply_changes(self, save=True):
if self.errors:
raise ValueError("The %s could not be changed because the data didn't validate." % opts.object_name)
clean_data = self.clean_data
for f in opts.fields + opts.many_to_many:
if isinstance(f, models.AutoField):
continue
setattr(instance, f.attname, clean_data[f.name])
if save:
instance.save()
return instance
return apply_changes
def form_for_model(model, form=BaseForm):
"""
Returns a Form class for the given Django model class.
Provide 'form' if you want to use a custom BaseForm subclass.
"""
opts = model._meta
field_list = []
for f in opts.fields + opts.many_to_many:
formfield = f.formfield()
if formfield:
field_list.append((f.name, formfield))
fields = SortedDictFromList(field_list)
return type(opts.object_name + 'Form', (form,), {'fields': fields, '_model': model, 'create': create})
def form_for_instance(instance, form=BaseForm):
"""
Returns a Form class for the given Django model instance.
Provide 'form' if you want to use a custom BaseForm subclass.
"""
model = instance.__class__
opts = model._meta
field_list = []
for f in opts.fields + opts.many_to_many:
current_value = f.value_from_object(instance)
formfield = f.formfield(initial=current_value)
if formfield:
field_list.append((f.name, formfield))
fields = SortedDictFromList(field_list)
return type(opts.object_name + 'InstanceForm', (form,),
{'fields': fields, '_model': model, 'apply_changes': make_apply_changes(opts, instance)})
def form_for_fields(field_list):
"Returns a Form class for the given list of Django database field instances."
fields = SortedDictFromList([(f.name, f.formfield()) for f in field_list])
return type('FormForFields', (BaseForm,), {'fields': fields})