Created
August 6, 2014 15:09
-
-
Save wiura/6fb338d05fa4b7c61371 to your computer and use it in GitHub Desktop.
Mix in fields to django model form.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Mix in fields to django model form. | |
| """ | |
| from django.conf import settings | |
| settings.configure() | |
| from django import forms | |
| from django.db import models | |
| class Model(models.Model): | |
| some_data = models.CharField(max_length=100) | |
| some_extra = models.CharField(max_length=100) | |
| class Meta: | |
| app_label = 'test' | |
| class AMixin(object): | |
| __metaclass__ = forms.forms.DeclarativeFieldsMetaclass | |
| a = forms.CharField(max_length=50) | |
| class BMixin(object): | |
| __metaclass__ = forms.forms.DeclarativeFieldsMetaclass | |
| b = forms.CharField(max_length=50) | |
| class ModelForm(forms.ModelForm): | |
| class Meta: | |
| model = Model | |
| fields = ['some_data'] | |
| def save(self, *args, **kwargs): | |
| cleaned_data = self.clean() | |
| # Do real save instead of this | |
| print 'cleaned_data', cleaned_data | |
| Model( | |
| some_data=cleaned_data['some_data'], | |
| some_extra='%s%s' % (cleaned_data['a'], cleaned_data['b']) | |
| ) | |
| class ModelFormMetaclassWithMixins( | |
| forms.forms.DeclarativeFieldsMetaclass, | |
| forms.models.ModelFormMetaclass | |
| ): | |
| def __new__(cls, name, bases, attrs): | |
| # new form with fields from ModelForm | |
| new_class = super(ModelFormMetaclassWithMixins, cls).__new__( | |
| cls, name, bases, attrs | |
| ) | |
| # mixins waiting to be mixin | |
| mixins = [ | |
| b for b in bases | |
| if type(b) == forms.forms.DeclarativeFieldsMetaclass | |
| ] | |
| # mixin fields waiting to be mixin | |
| mixin_fields = forms.forms.get_declared_fields(mixins, attrs, True) | |
| # mix in new fields | |
| new_class.base_fields.update(mixin_fields) | |
| return new_class | |
| def get_form(name, mixins, model_form): | |
| bases = [model_form] | |
| bases.extend(mixins) | |
| new_class = ModelFormMetaclassWithMixins(name, tuple(bases), {}) | |
| return new_class | |
| data = { | |
| 'some_data': 'some_data_post', | |
| 'a': 'a_post', | |
| 'b': 'b_post' | |
| } | |
| form = get_form('MyForm', [AMixin, BMixin], ModelForm)(initial=data) | |
| print 'fields', form.fields | |
| print form.as_p() | |
| form = get_form('MyForm', [AMixin, BMixin], ModelForm)(data) | |
| if form.is_valid(): | |
| form.save() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment