Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is meant by "Not a valid choice" when using wtform validation for one field?

I'm getting an incomprehensible error message when using validation for dynamic option (where options in one select field depend on the choice in the other selectfield. I can however not select a city once a region has been selected. Why not? What must be done?

 for city in montaomodel.City.all().fetch(99999):  # TODO: only do this for the region
     try:
         form.area.choices.insert(long(city.key().id()),
         (str(city.key().id()), 'Select...'))
     except:
         pass

My entire code block for inserts and validation is as follows.

class AdLister(BaseRequestHandler,
               blobstore_handlers.BlobstoreUploadHandler):
    csrf_protect = False

    def post(self):
        logging.info("i post")
        ad = Ad()
        if users.get_current_user():
            ad.user = users.get_current_user()

        if self.current_user is not None:
            try:
                ad.usr = self.current_user
            except Exception, e:
                logging.info('exception %s' % str(e))
        logging.info("i post2")
        if self.request.get('type'):
            ad.type = self.request.get('type')
        if self.request.get('address'):
            ad.address = self.request.get('address')
        if self.request.get('rooms'):
            ad.number_of_rooms = int(self.request.get('rooms'))
        if self.request.get('size'):
            ad.size = float(self.request.get('size'))
        if self.request.get('regdate'):
            ad.regdate = int(self.request.get('regdate'))
        if self.request.get('mileage'):
            ad.mileage = int(self.request.get('mileage'))

        ad.category = self.request.get('category_group')

        form = AdForm(self.request.params)
        logging.info("i post23")
        if self.request.get('area'):
            for city in montaomodel.City.all().fetch(99999):  # TODO: only do this for the region
                #logging.info("i post232")
                #logging.info("region%s" , city.region.key().id())
                try:
                    form.area.choices.insert(str(long(city.key().id())),
                                     (str(city.key().id()), 'Select...'))
                except:
                    pass
        logging.info("i post3")
        if form.validate():
            title = to_unicode_or_bust(form.title.data)
            #unicode(form.title.data, 'utf-8')
            ad.title = title
            self.session['title'] = ad.title
            name = to_unicode_or_bust(form.name.data)  #, 'utf-8')
            ad.name = name
            self.session['name'] = ad.name
            ad.email = form.email.data
            self.session['email'] = ad.email
            ad.phoneview = form.phoneview.data
            self.session['phoneview'] = ad.phoneview
            try:
                if form.phonenumber.data:
                    ad.phonenumber = form.phonenumber.data
                    self.session['phonenumber'] = ad.phonenumber
            except:
                pass

            text = to_unicode_or_bust(form.text.data)  # , 'utf8')
            titletest = to_unicode_or_bust(form.title.data)



            ad.text = text
            self.session['text'] = ad.text
            ad.price = form.price.data.replace(' ', '').replace(',00',
                                                                '').replace('.00', '')
            try:
                if form.price.data:
                    ad.integer_price = form.price.data.replace(' ', ''
                    ).replace(',00', '').replace('.00', '')
            except:
                pass
            self.session['price'] = ad.price
            ad.url = self.request.host
            self.session['url'] = self.request.host
            ad.place = self.request.get('place')
            self.session['place'] = ad.place
            ad.postaladress = self.request.get('place')
            self.session['postaladress'] = ad.postaladress
            ad.put()
            self.session['ad_id'] = ad.key().id()
        else:

            self.render('createnewad.html', {
                'user': self.current_user,
                'session': self.auth.get_user_by_session(),
                'request': self.request,
                'form': form,
                'name': to_unicode_or_bust(form.name.data)  #.encode('utf-8')
            })
            return
        if self.request.get('currency'):
            ad.currency = self.request.get('currency')
            self.session['currency'] = ad.currency
        if self.request.get('cg'):
            ad.category = self.request.get('cg')
            self.session['category'] = ad.category
        if self.request.get('company_ad') == '1':
            ad.company_ad = True
            self.session['company_ad'] = 'True'
        ad.put()

        ad.url = self.request.host

        for upload in self.get_uploads():
            try:
                img = Image(reference=ad)
                img.primary_image = upload.key()
                image_url = images.get_serving_url(str(upload.key()), size=640)
                img.put()
                ad.hasimages = True
                ad.image_url = images.get_serving_url(str(upload.key()), size=640)
                ad.put()
                ad.blobs.append(upload.key())
                ad.put()
            except Exception, e:
                logging.error('There was an exception:%s' % str(e))
                pass
        ad.published = False
        if self.request.get('area'):
            city = \
                montaomodel.City.get_by_id(long(self.request.get('area'
                )))
            region = montaomodel.Region.get(city.region.key())
            ad.cities.append(city.key())
            ad.regions.append(region.key())
            ad.city = unicode(city.name)
            ad.region = unicode(region.name)


        ad.put()
        if self.current_user:
            ad.userID = str(self.current_user.auth_ids[0])
            ad.put()
            ad.usr = self.current_user.key.to_old_key()
            ad.put()

        image = ad.matched_images.get()
        image_url = None
        if image:
            if image.primary_image:
                try:
                    image_url = \
                        images.get_serving_url(str(image.primary_image.key()),
                                               size=640)
                except Exception, e:
                    image_url = '/images/' + str(image.key().id()) \
                                + '_small.jpg'
            else:
                image_url = '/images/' + str(image.key().id()) \
                            + '_small.jpg'
        imv = []
        for i in ad.matched_images:
            if i.primary_image:
                try:
                    i1 = \
                        images.get_serving_url(str(i.primary_image.key()))
                    imv.append(i1)
                except Exception, e:
                    i1 = '/images/' + str(image.key().id()) \
                         + '_small.jpg'
                    imv.append(i1)

        if ad.price:  # and doesn't contain separators
            try:
                price = \
                    i18n.I18n(self.request).format_decimal(int(ad.price))
            except Exception, e:
                price = ad.price
        else:
            price = ad.price

        self.render('preview.html', {
            'user': self.current_user,
            'session': self.auth.get_user_by_session(),
            'request': self.request,
            'ad': ad,
            'image_url': image_url,
            'imv': imv,
            'len': len(imv),
            'form': PreviewAdForm(),
            'price': price,
            })

My form class looks as follows.

class AdForm(Form):
    categories = [
        ('1', _('All categories')),
        ('disabled', _('VEHICLES')),
        ('2010', _('Cars')),
        ('3', _('Motorcycles')),
        ('4', _('Accessories & Parts')),
        ('disabled', _('PROPERTIES')),
        ('7', _('Apartments')),
        ('8', _('Houses')),
        ('9', _('Commercial properties')),
        ('10', _('Land')),
        ('disabled', _('ELECTRONICS')),
        ('12', _('Mobile phones & Gadgets')),
        ('13', _('TV/Audio/Video/Cameras')),
        ('14', _('Computers')),
        ('disabled', _('HOME & PERSONAL ITEMS')),
        ('16', _('Home & Garden')),
        ('17', _('Clothes/Watches/Accessories')),
        ('18', _('For Children')),
        ('disabled', _('LEISURE/SPORTS/HOBBIES')),
        ('20', _('Sports & Outdoors')),
        ('21', _('Hobby & Collectables')),
        ('22', _('Music/Movies/Books')),
        ('23', _('Pets')),
        ('20', _('BUSINESS TO BUSINESS')),
        ('24', _('Hobby & Collectables')),
        ('25', _('Professional/Office equipment')),
        ('26', _('Business for sale')),
        ('disabled', _('JOBS & SERVICES')),
        ('28', _('Jobs')),
        ('29', _('Services')),
        ('30', _('Events & Catering')),
        ('31', _('Others')),
        ('1000', _('Sports & Outdoors')),
        ('1010', _('Hobby & Collectables')),
        ('1020', _('Hobby & Collectables')),
        ('1030', _('Music/Movies/Books')),
        ('1050', _('Pets')),
        ('1080', _('BUSINESS TO BUSINESS')),
        ('1100', _('Hobby & Collectables')),
        ('1090', _('Professional/Office equipment')),
        ('2010', _('Business for sale')),
        ('2030', _('Sports & Outdoors')),
        ('2040', _('Hobby & Collectables')),
        ('2080', _('Music/Movies/Books')),
        ('2070', _('Pets')),
        ('3000', _('BUSINESS TO BUSINESS')),
        ('3040', _('Hobby & Collectables')),
        ('3050', _('Professional/Office equipment')),
        ('3060', _('Business for sale')),
        ('4000', _('Sports & Outdoors')),
        ('4010', _('Hobby & Collectables')),
        ('4020', _('Music/Movies/Books')),
        ('4040', _('Pets')),
        ('4030', _('BUSINESS TO BUSINESS')),
        ('4090', _('Hobby & Collectables')),
        ('4060', _('Professional/Office equipment')),
        ('4070', _('Business for sale')),
        ('5030', _('Music/Movies/Books')),
        ('5020', _('Pets')),
        ('5010', _('BUSINESS TO BUSINESS')),
        ('5040', _('Hobby & Collectables')),
        ('6010', _('Professional/Office equipment')),
        ('6020', _('Business for sale')),
        ('6030', _('Music/Movies/Books')),
        ('6040', _('Pets')),
        ('7010', _('BUSINESS TO BUSINESS')),
        ('Other', _('Hobby & Collectables')),
    ]

    regions = [('', _('Choose')), ('3', _('Delhi')), ('4', _('Maharasta'
    )), ('7', _('Gujarat'))]
    cities = [('', _('«Choose city»')), ('3', _('Mumbai')), ('4',
                                                             _('Delhi'))]
    nouser = HiddenField(_('No user'))  # dummy variable to know whether user is logged in
    name = TextField(_('Name'),
                     [validators.Required(message=_('Name is required'
                     ))], widget=MontaoTextInput())
    title = TextField(_('Subject'),
                      [validators.Required(message=_('Subject is required'
                      ))], widget=MontaoTextInput())
    text = TextAreaField(_('Ad text'),
                         [validators.Required(message=_('Text is required'
                         ))], widget=MontaoTextArea())
    phonenumber = TextField(_('Phone'), [validators.Optional()])
    type = TextField(_('Type'),
                     [validators.Required(message=_('Type is required'
                     ))])
    phoneview = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'), [validators.Regexp('^[0-9]+$',
                                                     message=_(
                                                         'This is not an integer number, please see the example and try again'
                                                     )), validators.Optional()], widget=MontaoTextInput())
    email = TextField(_('Email'),
                      [validators.Required(message=_('Email is required'
                      )),
                       validators.Email(message=_('Your email is invalid'
                       ))], widget=MontaoTextInput())

    area = SelectField(_('City'), choices=cities,
                       validators=[validators.Optional()])
    category_group = SelectField(_('Category'), choices=categories,
                                 validators=[validators.Required(message=_('Category is required'
                                 ))])

    def validate_name(form, field):
        if len(field.data) > 50:
            raise ValidationError(_('Name must be less than 50 characters'
            ))

    def validate_email(form, field):
        if len(field.data) > 60:
            raise ValidationError(_('Email must be less than 60 characters'
            ))

    def validate_price(form, field):
        if len(field.data) > 8:
            raise ValidationError(_('Price must be less than 9 integers'
            ))
    def validate_area(form, field):
        if len(field.data) > 888:
            raise ValidationError(_('Dummy validator'
            ))
like image 790
Niklas Rosencrantz Avatar asked Apr 20 '15 15:04

Niklas Rosencrantz


1 Answers

Here you have an code example (1 Province has N Cities):

class ProvinceField(forms.ModelChoiceField):
    def __init__(self, query=Province.objects.all().order_by('name')):
        super(ProvinceField, self).__init__(queryset=query)

class CityField(forms.ModelChoiceField):    
    def __init__(self, query=City.objects.none()):
        super(CityField, self).__init__(queryset=query)

class CityForm(forms.Form)):
    province = ProvinceField()
    city = CityField()

    def __init__(self, *args, **kwargs):
        super(CityForm, self).__init__(*args, **kwargs)            
        if kwargs and kwargs.get('data').get('province'):
            try:
                province = Province.objects.get(pk=kwargs.get('data').get('province'))
            except ObjectDoesNotExist:
                self.fields['city'].queryset = City.objects.none()
            else:
                self.fields['city'].queryset = province.cities.all().order_by('name')
        else:
            self.fields['city'].queryset = City.objects.none()

I hope that this code will be helpful to you!

like image 72
Googuez Avatar answered Oct 19 '22 23:10

Googuez