I wanted to ask if someone know how to make a selection in a form where one of the choices is to add input
in my forms.py:
class InRes(forms.ModelForm):
class Meta:
model=Results
in my models.py:
PORT_STATUS=(
('FTP','21'),
('HTTP','443,80'),
)
class Results(models.Model):
status=models.CharField(max_length=5, choices=PORT_STATUS, default='HTTP')
i want to add and option to select one of the choices or entering my own input. any ideas?
Django forms are very picky when it comes to what is a valid choice, which is a good thing. It prevents malicious values from being passed in via manipulated POST data.
As such, you won't be able to programmatically add a choice, for one, because your choices are a hard-coded tuple, and two, because whatever choice you add won't be part of the choices the form considers valid when clean
is run, because the value wasn't there when the form was initialized.
Instead, consider making the choices a separate model, and provide a separate form field to add a record for that model, so that next time, the choice will be present.
Django forms can have a mixture of model and non-model fields, so use that to add the input field. You could also control the visibility of the extra field via JavaScript. It's probably possible to combine all of this into a multi-widget for a custom field.
# theoretical code, not tested
class PortStatus(models.Model):
status = models.CharField(max_length=100)
def __unicode__(self):
return self.status
# I prefer singular model names
class Result(models.Model):
status = models.ForeignKey(PortStatus, blank=True)
class ResultsForm(forms.ModelForm):
class Meta:
model = Result
extra_choice = forms.CharField(max_length=100, required=False)
def __init__(self, *args, **kwargs):
super(ResultsForm, self).__init__(*args, **kwargs)
self.save_new_status = False
def clean(self):
cleaned_data = self.cleaned_data()
status = cleaned_data.get('status')
extra_choice = cleaned_data.get('extra_choice')
if status and extra_choice:
raise forms.ValidationError("Can't specify both")
if not status and not extra_choice:
raise forms.ValidationError('Make a selection or add status')
if not status and extra_choice:
# make sure extra_choice isn't already in choices
if PostStatus.objects.filter(
status__iexact=extra_choice).count() > 0:
raise forms.ValidationError('Status present, etc')
else:
self.save_new_status = True
return cleaned_data
def save(self, commit=True)
instance = super(ResultsForm, self).save(commit=False)
if self.save_new_status:
new_status = PostStatus.objects.create(
status=self.cleaned_data.get('extra_choice'))
self.status = new_status
if commit:
instance.save()
return instance
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.