我有一个包含不绑定到模型的元素的表单。在某些情况下,该表单元素根本不会在HTML中呈现,但是当我发布表单时,如果它不存在,我希望它仍然可以进行验证。
我研究了将发布的值更改为某种值的可能性,但看不到这样做的方法。我已经尝试重写clean方法,但是我不确定您是如何做到的。我尝试将其设置为required = False,但这没有任何效果,因为它似乎至少需要发布一个空值。
我的表单类如下:
class StimForm(ModelForm):
body = forms.CharField( widget=forms.Textarea )
userstims = forms.ChoiceField(required=False)
class Meta:
model = Stim
fields = ['body','privacytype','stimtype']
HTML如下。由于这可能是隐藏的,因此在某些情况下不会发布用户的数据。在这些情况下,我仍然希望表单验证有效。
<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>
更新-视图:
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 })
更新-初始化方法
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)
)
答案 0 :(得分:0)
在您的__init__
方法中,您将完全重新定义userstims
字段,并用一个未设置required=False
的新字段覆盖它。您应该在重新定义中传递该选项,或者最好避免重新定义整个字段,而直接设置选择:
self.fields['userstims'].choices = mystims
还请注意,您的循环最好写成列表理解:
mystims = [(stim.id,stim.stimname) for stim in mystimqs]