Skip to content

Instantly share code, notes, and snippets.

@javaguirre
Created December 31, 2011 16:59
Show Gist options
  • Save javaguirre/1544570 to your computer and use it in GitHub Desktop.
Save javaguirre/1544570 to your computer and use it in GitHub Desktop.
Changing showed form field in ManyToManyFields, Django
from django import forms
from django.forms import ModelForm
from links.models import Link, Tag
from django.forms.util import ErrorList
def model_to_dict(instance, fields=None, exclude=None):
"""
Returns a dict containing the data in ``instance`` suitable for passing as
a Form's ``initial`` keyword argument.
``fields`` is an optional list of field names. If provided, only the named
fields will be included in the returned dict.
``exclude`` is an optional list of field names. If provided, the named
fields will be excluded from the returned dict, even if they are listed in
the ``fields`` argument.
"""
# avoid a circular import
from django.db.models.fields.related import ManyToManyField
opts = instance._meta
data = {}
for f in opts.fields + opts.many_to_many:
if not f.editable:
continue
if fields and not f.name in fields:
continue
if exclude and f.name in exclude:
continue
if isinstance(f, ManyToManyField):
# If the object doesn't have a primry key yet, just use an empty
# list for its m2m fields. Calling f.value_from_object will raise
# an exception.
if instance.pk is None:
data[f.name] = []
else:
data[f.name] = ", ".join([obj.slug for obj in f.value_from_object(instance)])
else:
data[f.name] = f.value_from_object(instance)
return data
class LinkForm(ModelForm):
tags = forms.ModelMultipleChoiceField(
queryset=Tag.objects.all(),
widget=forms.Textarea
)
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None, error_class=ErrorList, label_suffix=':',
empty_permitted=False, instance=None):
opts = self._meta
if instance is None:
if opts.model is None:
raise ValueError('ModelForm has no model class specified.')
# if we didn't get an instance, instantiate a new one
self.instance = opts.model()
object_data = {}
else:
self.instance = instance
object_data = model_to_dict(instance, opts.fields, opts.exclude)
# if initial was provided, it should override the values from instance
if initial is not None:
object_data.update(initial)
# self._validate_unique will be set to True by BaseModelForm.clean().
# It is False by default so overriding self.clean() and failing to call
# super will stop validate_unique from being called.
self._validate_unique = False
super(ModelForm, self).__init__(data, files, auto_id, prefix, object_data,
error_class, label_suffix, empty_permitted)
class Meta:
model = Link
fields = ('title', 'url', 'description', 'tags')
class UploadFileForm(forms.Form):
file = forms.FileField()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment