具有可能不存在的元素的Django处理表单

时间:2019-04-19 11:31:50

标签: html django django-forms

我有一个包含不绑定到模型的元素的表单。在某些情况下,该表单元素根本不会在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)
        )

1 个答案:

答案 0 :(得分:0)

在您的__init__方法中,您将完全重新定义userstims字段,并用一个未设置required=False的新字段覆盖它。您应该在重新定义中传递该选项,或者最好避免重新定义整个字段,而直接设置选择:

self.fields['userstims'].choices = mystims

还请注意,您的循环最好写成列表理解:

mystims = [(stim.id,stim.stimname) for stim in mystimqs]