首页 > 解决方案 > django 在提交定义之前阻止访问变量

问题描述

我有以下 django 视图,除了在我发送 POST 信息的上一个视图上单击提交按钮的实例之外,它的效果很好。

def submitted(request):
# sets the employeentname to the username from the POST of results
    owner = ADMirror.objects.get (employeentname=request.POST.get('userpost'))
# sets the firstname of owner
    firstname = owner.employeefirstname
# sets the lastname of owner
    lastname = owner.employeelastname
# gets the POST list for the report_id values in the checkboxes for application names
    checkedlist = request.POST.getlist('report_id')
    reportdetail = QvReportList.objects.filter(report_id__in = checkedlist).values_list('report_name_sc', flat = True).distinct()



# gets the timestamp from the system clock when the submit button is pressed
    access_request_date = timezone.now()
####  Unused at this time, but we can pull the division CFO and facility CFO based on the tables Gregg created in the SQL server database.  We'll let the workflow tool handle this part.
#    facilitycfo =  QvDatareducecfo.objects.filter(dr_code__exact = '34222', active = 1, cfo_type = 1).values_list('cfo_ntname', flat = True)
#    divisioncfo =  QvDatareducecfo.objects.filter(dr_code__exact = '34222', active = 1, cfo_type = 2).values_list('cfo_ntname', flat = True)
    #print (facilitycfo)
    #print (divisioncfo)
# gets the access level ie facility, division, market, group, corporate from the results.html POST request sent to submitted.html
    selectedaccesslevel = request.POST.get('accesslevelid')
# sets access level name and organization level name for the submitted page
    if request.method == 'POST' and selectedaccesslevel == '3':
        accesslevel = 'company-wide access'
        orglevelname = ''
    if request.method == 'POST' and selectedaccesslevel == '4':
        accesslevel = 'group level access'
        accesslevelname = request.POST.getlist('blevel')
        orglevelname = FacilityDimension.objects.filter(b_level__in = accesslevelname).values_list('group_name', flat = True).distinct()
    if request.method == 'POST' and selectedaccesslevel == '5':
        accesslevel = 'division level access'
        accesslevelname = request.POST.getlist('rlevel')
        orglevelname = FacilityDimension.objects.filter(r_level__in = accesslevelname).values_list('division_name', flat = True).distinct()
    if request.method == 'POST' and selectedaccesslevel == '6':
        accesslevel = 'market level access'
        accesslevelname = request.POST.getlist('dlevel')
        orglevelname = FacilityDimension.objects.filter(d_level__in = accesslevelname).values_list('market_name', flat = True).distinct()

    if request.method == 'POST' and selectedaccesslevel == '7':
        accesslevel = 'facility level access'
        accesslevelname = request.POST.getlist('zcoid')
        orglevelname = FacilityDimension.objects.filter(coid__in = accesslevelname).values_list('coid_name', flat = True).distinct()




# gets the PHI boolean flag from the results.html POST request sent to submitted.html
    selectedphi = request.POST.get('phi')

# if statements to define hte datarduce code based on the selected access level sent from the results.html POST
## corporate
    if request.method == 'POST' and selectedaccesslevel == '3':
        selectlist = "S00001"
# group
    if request.method == 'POST' and selectedaccesslevel == '4':
        selectlist = request.POST.getlist('blevel')
# division
    if request.method == 'POST' and selectedaccesslevel == '5':
        selectlist = request.POST.getlist('rlevel')
# market
    if request.method == 'POST' and selectedaccesslevel == '6':
        selectlist = request.POST.getlist('dlevel')
# facility
    if request.method == 'POST' and selectedaccesslevel == '7':
        selectlist = request.POST.getlist('zcoid')
        selectlist = [f'Z{value}' for value in selectlist]

# nested if/for statement which writes to the [QlikView].[dbo].[QV_FormAccessRequest] table if a corporate access level is selected the datareduce code is set to S00001
    if request.method == 'POST':
        for i in checkedlist:
            if selectedaccesslevel == '3':
                    requestsave = QVFormAccessRequest(ntname = 'HCA\\'+owner.employeentname, first_name = owner.employeefirstname, last_name = owner.employeelastname, coid = owner.coid, title = owner.title
                                                    ,report_id = i, accesslevel_id = selectedaccesslevel, phi = selectedphi , access_beg_date = access_request_date, previousdatareducecode = '',  datareducecode = 'S00001', facility = owner.facilityname, requestid = '0', requesttype = 'New')# = list(facilitycfo)[0], division_cfo = list(divisioncfo)[0] )
                    requestsave.save()
# part of the nested if/for statement above which writes to [QlikView].[dbo].[QV_FormAccessRequest] if anything other than corporate user is selected it will chose the correct data reduce code based on the select list if statements above.
            else:
                for j in selectlist:
                    requestsave = QVFormAccessRequest(ntname = 'HCA\\'+owner.employeentname, first_name = owner.employeefirstname, last_name = owner.employeelastname, coid = owner.coid, title = owner.title
                                            ,report_id = i, accesslevel_id = selectedaccesslevel, phi = selectedphi , access_beg_date = access_request_date,previousdatareducecode = '', datareducecode = j, facility = owner.facilityname,requestid = '0', requesttype = 'New' )# = list(facilitycfo)[0], division_cfo = list(divisioncfo)[0] )
                    requestsave.save()

    args = {'firstname' : firstname, 'lastname' : lastname, 'owner' : owner, 'accesslevel':accesslevel, 'reportdetail':reportdetail, 'orglevelname':orglevelname}
    return render(request, 'submitted.html', args)

我的表单上有多个按钮,所以我不能使用 required 因为它会干扰另一个按钮的操作,所以我使用以下 javascript 验证。

function submitFormSub(action) {
  var form = document.getElementById('form1');
  form.action = action;
  var accesslevelid = document.getElementById('accesslevelid');
  if (form.action == 'submitted')
  {
    if ($('#accesslevelid').val() == "")
  {
      alert('Please select an access level');
      return false;
    }

    form.submit();
  }

}

上面的验证效果很好,因为我看到了警报,但是表单仍然尝试提交,我收到了以下错误。

local variable 'accesslevel' referenced before assignment

标签: django

解决方案


几个选项:

1) 将您的表单转换为 Django Form,以便您可以覆盖验证方法,从而在is_valid调用其方法并失败时让表单回退。那几乎可以肯定是最干净的。您还可以使用字段上的关键字定义不同的选择choices,并清理大量不必要的代码。

2)调用selectedaccesslevel = request.POST.get('accesslevelid', None)None跳过以呈现返回,而无需尝试设置访问级别并且不处理表单以创建QVFormAccessRequest实例的逻辑。

解释:

selectedaccesslevel = request.POST.get('accesslevelid', None)
if selectedaccesslevel:
   # all your code that defines and sets access levels that you
   # don't want to run because it doesn't have a crucial bit of info
args = {'firstname' : firstname, 'lastname' : lastname, 'owner' : owner, 'accesslevel':accesslevel, 'reportdetail':reportdetail, 'orglevelname':orglevelname}
return render(request, 'submitted.html', args) 

推荐阅读