I have a form which contains an element that is not bound to a model. There are cases where this form element will not be rendered in the HTML at all, but when I post the form I want it to validate still if it doesn't exist.
I have looked into the possibility of changing the value that is posted to something, but can't see a way of doing this. I have tried overriding the clean method, but I am not sure how you do that. I have tried setting it to required=False, but that has no effect because it seems to require a null value to be posted at the very least.
My form class looks as below:
class StimForm(ModelForm):
body = forms.CharField( widget=forms.Textarea )
userstims = forms.ChoiceField(required=False)
class Meta:
model = Stim
fields = ['body','privacytype','stimtype']
The HTML is below. As this is possibly hidden the data for userstim is not posted in some cases. I still want the form validation to work in these cases.
<div class='form-group row' id="userstim" style="display:none;">
<label class="col-2 col-form-label">Add Custom Stim:</label>
<div class="col-5">
{{ form.userstims }}
</div>
<div class="col-5">
<a href="/stimbook/adduserstim">Add Stim</a>
</div>
</div>
UPDATE - The View:
def stimboard(request):
user = getuser(request)
if user == None:
#redirect
return HttpResponseRedirect('/user/login')
#Get the user defined stims if they exist
try:
userstims = UserStim.objects.filter(user=user)
except:
userstims = []
#Get the id of the user to look up
stimuser = User.objects.get(id=request.GET.get("id"))
#Get the user profile data
profiledata = getprofiledata(stimuser)
#forms
commentform = StimCommentForm()
if request.POST:
form = StimForm(request.POST,mystims=userstims)
userstimform = UserStimForm(request.POST)
if form.is_valid():
#Create stim
print("Creating Stim")
if form.cleaned_data['stimtype'] == "OT":
#Create custom stim
Stim.objects.create(
body = form.cleaned_data['body'],
poster = user,
board = stimuser,
privacytype = form.cleaned_data['privacytype'],
stimtype = form.cleaned_data['stimtype'],
otherstim = UserStim.objects.get(id=form.cleaned_data['userstims'])
)
else:
Stim.objects.create(
body = form.cleaned_data['body'],
poster = user,
board = stimuser,
privacytype = form.cleaned_data['privacytype'],
stimtype = form.cleaned_data['stimtype']
)
else:
form = StimForm(request.POST,mystims=userstims)
userstimform = UserStimForm()
#Get friendship status of user
buddystatus = Buddy.buddies.buddystatus(user,stimuser)
#Get public stims from user
stims = Stim.objects.filter(board=stimuser,privacytype="PU")
#Check if buddy and get private stims then add them to the stims
isbuddy = Buddy.buddies.isbuddy(user,stimuser)
if isbuddy:
privatestims = Stim.objects.filter(board=stimuser,privacytype="PR")
stims = stims | privatestims
stimlist = []
#get the comments for each stim
for stim in stims:
stimdict = dict()
stimdict['id'] = stim.id
stimdict['poster'] = stim.poster
stimdict['body'] = stim.body
stimdict['dateofpost'] = stim.dateofpost
stimdict['privacytype'] = stim.privacytype
if stim.stimtype == "OT":
#get the custom stim
stimdict['stimtype'] = stim.otherstim.stimname
else:
print(type(stim.stimtype))
stimdict['stimtype'] = getstimtype(stim.stimtype)
stimdict['stimcomments'] = StimComment.objects.filter(stim=stim)
stimlist.append(stimdict)
stimlist.sort(key=lambda x: x['dateofpost'], reverse=True)
return render(request, 'stimboard/stimboard.html', { 'stimuser' : stimuser, 'stims' : stimlist, 'buddystatus' : buddystatus,
'commentform' : commentform, 'form' : form, 'userstimform' : userstimform,
'isbuddy' : isbuddy, 'profiledata' : profiledata })
UPDATE - The init method
def __init__(self, *args, **kwargs):
mystimsqs = kwargs.pop('mystims')
super(StimForm, self).__init__(*args, **kwargs)
print("kwargs")
mystims = []
for stim in mystimsqs:
stimlist = (stim.id,stim.stimname)
mystims.append(stimlist)
self.fields['userstims'] = forms.ChoiceField(
choices=tuple(mystims)
)