Форма процесса Django с элементом, который может не существовать

#html #django #django-forms

#HTML #Django #django-forms

Вопрос:

У меня есть форма, которая содержит элемент, который не привязан к модели. Бывают случаи, когда этот элемент формы вообще не отображается в HTML, но когда я отправляю форму, я хочу, чтобы она все еще проверялась, если она не существует.

Я рассмотрел возможность изменения значения, которое публикуется для чего-либо, но не вижу способа сделать это. Я попытался переопределить метод clean, но я не уверен, как вы это делаете. Я попытался установить для него значение required=False, но это не имеет никакого эффекта, потому что, похоже, требуется, чтобы по крайней мере было опубликовано значение null.

Мой класс формы выглядит следующим образом:

 class StimForm(ModelForm):
    body = forms.CharField( widget=forms.Textarea )
    userstims = forms.ChoiceField(required=False)

    class Meta:
        model = Stim
        fields = ['body','privacytype','stimtype']
 

HTML приведен ниже. Поскольку это, возможно, скрыто, данные для userstim в некоторых случаях не публикуются. Я все еще хочу, чтобы проверка формы работала в этих случаях.

   <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. Этот вопрос неясен. Если поле не является обязательным, то форма действительна без него. В чем именно проблема, с которой вы столкнулись?

2. HTML показывает div, для которого установлено значение no display через атрибут style . Если он не отображается, то {{ form.userstims }} вообще не публикуется, что означает сбой при проверке формы, потому что он вообще не существует.

3. Нет, это не приведет к сбою; userstims поле имеет значение required=False . Если вы получаете сообщение об ошибке, покажите все это вместе с соответствующим представлением.

4. Ниже я ответил на то, что работает, но это не идеальное решение.

Ответ №1:

В вашем __init__ методе вы полностью переопределяете userstims поле, перезаписывая его новым полем, у которого нет required=False set . Вы должны либо передать эту опцию в переопределении, либо лучше избегать переопределения всего поля и просто задавать варианты напрямую:

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

Также обратите внимание, что ваш цикл лучше записать в виде списка для понимания:

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

Комментарии:

1. Большое спасибо, я расскажу об этом позже и дам вам знать.

2. Большое спасибо, теперь это, похоже, работает. Также спасибо за советы по пониманию списка. Я все еще изучаю это.