how to get text of a ChoiceField populated with ajax

1,491 views
Skip to first unread message

HDayi

unread,
May 8, 2012, 3:59:19 AM5/8/12
to Django users
hi people,
i am new to all of this.
i have a form which has several selcet boxes. one is a
ModelChoiceField gets school list from database. the other is only a
ChoiceField and it's empty. when school is chosen i populate the
ChoiceField using dajax. it works perfectly but...

while validating the form when calculating the cleaned_data value
returns index of the selected item and django does not validate the
form.

can you help me on this?
thx

francescortiz

unread,
May 8, 2012, 3:35:41 PM5/8/12
to django...@googlegroups.com
You have to make sure that the javascript code that populates the second select box sets the value properly, or create a custom form validation (custom form/field clean methods).

Kurtis Mullins

unread,
May 8, 2012, 4:11:21 PM5/8/12
to django...@googlegroups.com
cleaned_data should return the value of the field, not the index. Did you create your own clean__fieldname method?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/ezZh3lD2mRcJ.

To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

HDayi

unread,
May 9, 2012, 7:39:21 AM5/9/12
to django...@googlegroups.com
hi Kurtis and Frances
after populating the ChoiceField it looks like this
   <select id="id_teacher" name="teacher">
       <option value="First">First</option>
       <option value="Second">Second</option>
   </select>
at first values were number but django form returns the value for this ChoiceField after validation.
I don't have a clean_teacher method because i don't know what to do.

i think the problem is that: when the form is first created coice list for this ChoiceField is empty. after that what ever it returns is not included in the choice list because it's empty. i need to add a choice list in the clean method but i don't know how.

when i gogled everybody was talking about a web page (django gotchas or someting like that) but link was always broken. :(

HDayi

unread,
May 9, 2012, 7:46:41 AM5/9/12
to django...@googlegroups.com
hi again,
finally i have solved the problem. I have found a web page saying you must create a custom choiceField class with a custom validation method. so i did that.

http://blog.ikraftsoft.com/post/1342312823/django-form-choicefield-dynamic-values

thx

Kurtis Mullins

unread,
May 9, 2012, 2:19:38 PM5/9/12
to django...@googlegroups.com
Hey,

It would help a lot to see your code posted to dpaste.com or somewhere. As far as grabbing the choices in your clean method, here's a little copy-and-paste from Django's own ChoiceField so you can see how they do it:

class ChoiceField(Field):
    widget = Select
    default_error_messages = {
        'invalid_choice': _(u'Select a valid choice. %(value)s is not one of the available choices.'),
    }

    def __init__(self, choices=(), required=True, widget=None, label=None,
                 initial=None, help_text=None, *args, **kwargs):
        super(ChoiceField, self).__init__(required=required, widget=widget, label=label,
                                        initial=initial, help_text=help_text, *args, **kwargs)
        self.choices = choices

    def __deepcopy__(self, memo):
        result = super(ChoiceField, self).__deepcopy__(memo)
        result._choices = copy.deepcopy(self._choices, memo)
        return result

    def _get_choices(self):
        return self._choices

    def _set_choices(self, value):
        # Setting choices also sets the choices on the widget.
        # choices can be any iterable, but we call list() on it because
        # it will be consumed more than once.
        self._choices = self.widget.choices = list(value)

    choices = property(_get_choices, _set_choices)

    def to_python(self, value):
        "Returns a Unicode object."
        if value in validators.EMPTY_VALUES:
            return u''
        return smart_unicode(value)

    def validate(self, value):
        """
        Validates that the input is in self.choices.
        """
        super(ChoiceField, self).validate(value)
        if value and not self.valid_value(value):
            raise ValidationError(self.error_messages['invalid_choice'] % {'value': value})

    def valid_value(self, value):
        "Check to see if the provided value is a valid choice"
        for k, v in self.choices:
            if isinstance(v, (list, tuple)):
                # This is an optgroup, so look inside the group for options
                for k2, v2 in v:
                    if value == smart_unicode(k2):
                        return True
            else:
                if value == smart_unicode(k):
                    return True
        return False

So, if you're creating your own ChoiceField, it looks like you'll need to do quite a bit of work. If you really need your own ChoiceField, it might be better to just subclass theirs.. However, I don't think you're doing anything too custom where Django's ChoiceField isn't enough. If you can post your code somewhere, I'll keep an eye out for this thread and try to help as much as I can.

 

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/FHF67cmYklQJ.

HDayi

unread,
May 18, 2012, 6:57:24 AM5/18/12
to django...@googlegroups.com
hi curtis,
sorry for being so late.

on the page i have given the url, it's told exactly how you said. I have subclassed djangos choicefield and just changed validation method that always return true. so my own clean_fieldname method started to work fine. I am checking the returned valu if exist in my database table.

Kurtis Mullins

unread,
May 23, 2012, 2:52:53 PM5/23/12
to django...@googlegroups.com
Hey, no problem! My apologies for missing out on this thread for a
while. I hope you got it figured out!

Anyways, I'm thinking that if you're actually basing this validation
(done in your clean method), you may want to use a ForeignKey Field.
You can define a custom queryset to filter through the results if you
only want certain teachers to be available.

Otherwise, you could put a method along these lines in your current Form class.

import Teacher
from (some django forms module) import ValidationError
class MyForm(Form):

...
def clean__teacher(self):
teacher = self.cleaned_data['teacher'] # Value of the chosen teacher
if Teacher.objects.filter(name=teacher).exists():
return True
else
raise ValidationError("You have chosen an invalid teacher")

Hopefully that helps a bit. If not, let me know and I'll try to help
some more :)
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/Y_isSMVE4lcJ.

Kurtis Mullins

unread,
May 23, 2012, 2:54:20 PM5/23/12
to django...@googlegroups.com
Sorry, somehow I completely overlooked the post where it says you've
solved the problem. Happy hacking!
Reply all
Reply to author
Forward
0 new messages