So my last post was a quick hack attempt at this, but I have come up with a much cleaner method of getting a GAE ListProperty field to work with Django Forms (newforms). You simply have to create a new form field called ListPropertyChoice:
from django.newforms.fields import MultipleChoiceField
from appengine_django.models import BaseModel
class ListPropertyChoice(MultipleChoiceField):
def clean(self, value):
""" extending the clean method to work with GAE keys """
new_value = super(ListPropertyChoice, self).clean(value)
key_list = []
for k in new_value:
key_list.append(BaseModel.get(k).key())
return key_list
You can then use this in your forms:
...
from fields import ListPropertyChoice
class Form(djangoforms.ModelForm):
my_model = ListPropertyChoice(
widget=forms.CheckboxSelectMultiple(),
choices=[(m.key(), m.name) for m in db.Query(MyModel)]
)
class Meta:
model = ParentModel
Obviously you can use both the SelectMultiple widget and the CheckboxSelectMultiple widget and this same process could be easily duplicated for ChoiceField:
class GAEChoiceField(ChoiceField):
def clean(self, value):
""" extending the clean method to work with GAE keys """
value = super(GAEChoiceField, self).clean(value)
return BaseModel.get(value).key()
8 responses so far ↓
SelectMultiple for a Google App Engine ListProperty using Django Forms « Pandemonium Illusion // August 20, 2008 at 2:03 am |
[...] 15, 2008 · 1 Comment EDIT: I recently posted a better way to do [...]
hugo // January 28, 2009 at 10:56 pm |
hey .. great post. it just does not validate here for me ;( would be glad if you could show how to actually dump this to datastore in the end, perhaps?
thx!
jamstooks // January 28, 2009 at 11:56 pm |
Hi hugo,
I just used this again the other day with the latest version of Django. Are you using the form’s save method?
The clean() methods return the values and then they are saved to BigTable using form.save().
When you say they aren’t “validating,” do you mean the form isn’t submitting? If so, you might make sure you’re populating your choices list correctly with ((‘key’,'name’),).
Hope that helps.
hugo // January 29, 2009 at 12:15 pm |
Hello jamstooks,
thanks for your fast reply.
the form looks all good here, it has the key’s as values and sends them over as a UnicodeMultiDict .. ([(u'my_tags', u'ahBpbnRlcm5ldHJhZGlvYm94cg8LEgRUYWdzIgVhbW91cgw'), (u'my_tags', u'ahBpbnRlcm5ldHJhZGlvYm94cg8LEgRUYWdzIgViYWlsZQw'), (u'my_tags', u'ahBpbnRlcm5ldHJhZGlvYm94cg8LEgRUYWdzIgVzYWxzYQw')])
my problem is, the clean_method of the ListPropertyChoice does not seem to like my data at all, when I try to pass it on e.g.:
data = TagForm(data=self.request.POST, instance=station)
data.errors tells me my_tagsEnter a list of values.
no luck with a list either..
data_raw = self.request.get(‘my_tags’, allow_multiple=True)
I’m using the exact code from your sample above, on the most recent vanilla GAE sdk.
Man, I wish I had posted this earlier ..
Would be so glad to get this done, finally ..
Cheers, Hugo
hugo // January 29, 2009 at 4:12 pm |
seems like there is only the first choice / element of the multidict/POST is passed to the validation/clean() method, and not the full choice that was made. I noticed that when the “for k in new_value” started decomposing the single key.. I’m clueless
hugo // January 30, 2009 at 11:45 am |
another question that raises, is the choices=[] populated on first run only, and not updated when there are new values? hope you bear with me
jamstooks // January 30, 2009 at 2:32 pm |
Good point about the population of choices only one time. Use an init function if you want to repopulate every time it’s displayed.
http://www.djangosnippets.org/snippets/26/
Andrew // May 29, 2009 at 8:37 pm |
To get more than one value use self.request.POST.mixed() instead of just self.request.POST when passing the data to the form.