'unicode' 对象没有属性 'get' django 动态表单集错误 is_valid()

'unicode' object has no attribute 'get' error in django dynamic formset is_valid()

所以我有一个表单集,我用它来构建一个基本的 html table,我可以在其中动态地将表单添加到 table 作为一行。

我遇到的问题是,当我 post 我的数据和 运行 我的 is_valid() 在我的表单集上时,我不断收到 'unicode' object has no attribute 'get' 异常

表格:

class ModbusRegistersForm(ModelForm):
    ixRegisterType = ModelChoiceField(queryset=RegisterType.objects.all()),
    class Meta:
        model = Register
        fields = ['sRegisterName','iStartingAddr','iEndingAddr','ixRegisterType','iOffset']
        widgets = {
                'sRegisterName': TextInput(attrs={'placeholder': 'Register Name','class': 'form-control', 'data-form': '0'}),
                'iStartingAddr': TextInput(attrs={'placeholder': 'Starting address','class': 'form-control','data-form': '0'}),
                'iEndingAddr': TextInput(attrs={'placeholder': 'Ending address','class': 'form-control','data-form': '0'}),
                'iOffset': TextInput(attrs={'placeholder': 'Address offset','class': 'form-control','data-form': '0'}),
            }

查看:

def create_modbus_view(request):
    assert isinstance(request, HttpRequest)


    modbus_device = CreateModbusForm()
    RegisterFormset = modelformset_factory(Register, form=ModbusRegistersForm)
    register_forms = RegisterFormset()

    return render(
        request,
        'app/create_modbus.html',
        context_instance = RequestContext(request,
        {
            'title':'Create Modbus Device',
            'tag': 'create_modbus',
            'modbus_device': modbus_device,
            'register_forms': register_forms
        })
    )

Ajax 查看接收 POST:

def ping_device(request):
    response_data = {}
    response_data['conn_result'] = '' 

    try:
        if request.method == 'POST':
            port = None
            slave = None
            ip = None

            modbus_device = CreateModbusForm(request.POST['form'])

            RegisterFormset = modelformset_factory(Register, form=ModbusRegistersForm)
            registers = RegisterFormset(request.POST['form'])

            if registers.is_valid(): #fails here
                for reg in registers.forms:
                    hi = "i never work"

            if modbus_device.is_valid():
                port = modbus_device['port']
                slave = modbus_device['slave_id']
                ip = modbus_device['ip_address']

                registers = modbus_device


            response_data['conn_result'] = mb_ping_result

            return JsonResponse(response_data)

    except Exception as e:
        response_data['conn_result'] = str(e)
        return JsonResponse(response_data)

EDIT 似乎我的 registers 表单集不包含 forms 属性,还有我的堆栈跟踪:

    Internal Server Error: /ping_device
Traceback (most recent call last):
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\core\handlers\base.py", line 132, in get_res
ponse
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\app\views.py", line 128, in ping_device
    for reg in registers.forms:
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\utils\functional.py", line 60, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\formsets.py", line 142, in forms
    forms = [self._construct_form(i) for i in range(self.total_form_count())]
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\formsets.py", line 115, in total_form_
count
    return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolut
e_max)
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\formsets.py", line 94, in management_f
orm
    if not form.is_valid():
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\forms.py", line 184, in is_valid
    return self.is_bound and not self.errors
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\forms.py", line 176, in errors
    self.full_clean()
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\forms.py", line 392, in full_clean
    self._clean_fields()
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\forms.py", line 401, in _clean_fields
    value = field.widget.value_from_datadict(self.data, self.files, self.add_pre
fix(name))
  File "C:\Users\jb.DOM\Desktop\BACnet Modbus\ModbusBACnet\BACnetModbus_
WebApp\env\lib\site-packages\django\forms\widgets.py", line 223, in value_from_d
atadict
    return data.get(name, None)
AttributeError: 'unicode' object has no attribute 'get'
[15/Sep/2015 17:20:14] "POST /ping_device HTTP/1.1" 500 17336

编辑 2 request.POST['form']内容:

HTTP/1.1" 200 16448
device_name=dev&csrfmiddlewaretoken=UrsGnQNnpEGVptIGXlEe2221AfdAzRv9&port=3&slav
e_id=3&ip_address=3&form-TOTAL_FORMS=2&form-INITIAL_FORMS=0&form-MIN_NUM_FORMS=0
&form-MAX_NUM_FORMS=1000&form-0-sRegisterName=est&form-0-iStartingAddr=5&form-0-
iEndingAddr=34&form-0-ixRegisterType=1&form-0-iOffset=1&form-1-sRegisterName=tes
t&form-1-iStartingAddr=5&form-1-iEndingAddr=34&form-1-ixRegisterType=1&form-1-iO
ffset=1

感谢 jlnabais post link,我之前确实看过那个答案,但没有完全理解,所以当你 post 编辑它时我回去弄明白了。

由于我使用的是 ajax,post 数据被转换为 unicode 字符串,所以当我尝试访问数据时,它无法解析该字符串。如果我在没有 ajax 的情况下这样做,那么它就可以工作。由于我坚持使用 ajax,我使用 urlparseQueryDict 来解析 unicode 数据并将其转换为字典。

RegisterFormset = modelformset_factory(Register, form=ModbusRegistersForm)

        if request.method == 'POST':

            my_dic = dict(urlparse.parse_qsl(request.POST['form']))    

            modbus_device = CreateModbusForm(my_dic)

            if modbus_device.is_valid():
                port = modbus_device.cleaned_data['iPort']
                slave = modbus_device.cleaned_data['iSlave']
                ip = modbus_device.cleaned_data['sIP']
            else:
                raise ValueError(modbus_device.errors)

            registers = RegisterFormset(QueryDict(request.POST['form']))
            for reg in registers.forms:
                if reg.is_valid():
                    container = RegisterContainer()
                    container.reg_name = reg.cleaned_data['sRegisterName']
                    container.reg_start_addr = reg.cleaned_data['iStartingAddr']
                    container.reg_range = reg.cleaned_data['bRange']
                    container.reg_type = reg.cleaned_data['ixRegisterType'].ixRegisterType
                    container.reg_offset = reg.cleaned_data['iOffset']

                    register_list.append(container)
                else:
                    raise ValueError(registers.errors)