Form Validation using Django Templates

2019-08-30 07:21发布

问题:

I created a form inside my template, my problem is to get data without using forms module.

(Update: I added my get pk from previous form and put it in my pt variable to insert in my table with patient field afterwards, the problem is it does not create new entry for my loop. I want to save tooth number and status)

class DentalRecordCreateView(CreateView):
    template_name = 'patient/dental_create.html'
    model = DentalRecord
    fields = '__all__'
    success_url = '/'

    def form_valid(self, form):
        tooth = [18, 17, 16, 15, 14, 13, 12, 11, 21, 22, 23, 24, 25, 26, 27, 28, 48, 47, 46, 45, 44, 43, 42, 41, 31, 32, 33, 34, 35, 36, 37, 38]
        tooth.reverse()
        mytooth = {}
        pt = self.kwargs['pk']

       for t in tooth:
           mytooth["{0}".format(t)] = self.request.POST.getlist('tooth_' + str(t),False) # returns value each textbox from form tooth. Value for tooth status [decayed, etc.]
           mytooth2 = " ".join(mytooth[str(t)])
           form.instance.status = mytooth2
           form.instance.position = str(t)
           form.instance.patient = PatientInfo.objects.get(pk=pt)

    return super(DentalRecordCreateView, self).form_valid(form)

Here is my model (Added)

class DentalRecord(models.Model):

    patient = models.ForeignKey(PatientInfo, on_delete=models.CASCADE, null=True, blank=True)
    position = models.CharField('Teeth',max_length=200,  null=True, blank=True)  # 22, 31
    status = models.CharField('Status',max_length=200,  null=True, blank=True)  # decayed
    topArea = models.BooleanField('TopArea', default=False)  # boolean
    rightArea = models.BooleanField('RightArea', default=False)  # boolean
    bottomArea = models.BooleanField('BottomArea', default=False)  # boolean
    leftArea = models.BooleanField('LeftArea', default=False)  # boolean
    centerArea = models.BooleanField('CenterArea', default=False)  # boolean

My template.html (Added)

<form method='post' action="" enctype='multipart/form-data'>
               {% csrf_token %}
               <table  class="table table-responsive" id="dental-chart">

                  <tr>
                     {% with '48 47 46 45 44 43 42 41 31 32 33 34 35 36 37 38' as list_lower %}
                     {% for y in list_lower.split %}
                     <td>
                        <svg width="50" height="50" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
                           width="10.8px" height="7.6px" viewBox="0 0 10.8 7.6" style="width:100%; enable-background:new 0 0 10.8 7.6;" xml:space="preserve">
                           <ellipse onClick="centerArea(this.id)" id="centerArea_{{ y }}"  name="centerArea_{{ y }}" class="ngipon" cx="5.4" cy="3.8" rx="2.7" ry="1.9"/>
                           <path onClick="leftArea(this.id)" id="leftArea_{{ y }}"  name="leftArea_{{ y }}" class="ngipon" d="M3.4,5.6C2.7,5.2,2.2,4.5,2.2,3.8c0-0.7,0.4-1.3,1-1.7L2,0.9C0.8,1.5,0,2.6,0,3.8
                              c0,1.3,0.9,2.4,2.2,3.1L3.4,5.6z"/>
                           <path onClick="topArea(this.id)" id="topArea_{{ y }}" name="topArea_{{ y }}" class="ngipon" d="M3.7,1.8c0.5-0.2,1.1-0.4,1.7-0.4C6,1.5,6.5,1.6,7,1.8l1.1-1.2C7.3,0.2,6.4,0,5.4,0
                              c-1.1,0-2.1,0.2-3,0.6L3.7,1.8z"/>
                           <path onClick="bottomArea(this.id)" id="bottomArea_{{ y }}" name="bottomArea_{{ y }}" class="ngipon" d="M7.1,5.8C6.6,6,6,6.2,5.4,6.2C4.8,6.2,4.3,6,3.8,5.8L2.6,7.1c0.8,0.3,1.7,0.5,2.7,0.5
                              c1.1,0,2.2-0.2,3-0.7L7.1,5.8z"/>
                           <path onClick="rightArea(this.id)" id="rightArea_{{ y }}" name="rightArea_{{ y }}" class="ngipon" d="M8.5,0.7L7.4,2c0.7,0.4,1.1,1.1,1.1,1.8c0,0.7-0.4,1.3-1,1.7l1.3,1.2C10,6,10.8,5,10.8,3.8
                              C10.8,2.5,9.9,1.4,8.5,0.7z"/>
                        </svg>
                     </td>
                     {% endfor %}
                  </tr>
                  <tr>
                     {% for y in list_lower.split %}
                     <td  class="col-sx-1"><input type="text" placeholder="{{ y }}" class="form-control" name="tooth_{{ y }}"></td>
                     {% endfor %}
                     {% endwith %}
                  </tr>
               </table>
               <div class="col-md-12">
                  <button id="dental" type="submit" class="btn btn-lg btn-primary pull-right btn-block">Submit</button>
               </div>
            </form>

The error says that (Updated)

'Could not send URL to django. Error 500. TypeError at /patient/dental/399 can only join an iterable' 

I find the I find the class based views confusing, does anyone have a good tutorial on how to use it for CRUD operations?

Thanks

回答1:

Override form_valid method you will directly get form object. Move your logic from post method to form_valid. remove post method as you already mention success_url attribute. no need to redirect it explicitly

class DentalRecordCreateView(CreateView):
    template_name = 'patient/dental_create.html'
    model = DentalRecord
    fields = '__all__'
    success_url = '/'

    def form_valid(self, form):
        tooth = [18, 17, 16, 15, 14, 13, 12, 11, 21, 22, 23, 24, 25, 26, 27, 28, 48, 47, 46, 45, 44, 43, 42, 41, 31, 32,
                     33, 34, 35, 36, 37, 38]
        tooth.reverse()
        mytooth = {}

        for t in tooth:
           mytooth["{0}".format(t)] = request.POST.getlist('tooth_' + str(t), [])  
           # returns value each textbox from form tooth. Value for tooth status [decayed, etc.]
           mytooth2 = " ".join(mytooth[str(t)])
           form.instance.status = mytooth2
           form.instance.position = t

        return super(DentalRecordCreateView, self).form_valid(form)

ClassBased views tutorial



标签: django forms