首页 > 解决方案 > Django:无法验证 MultipleChoiceField

问题描述

问题

我的MultipleChoiceField. 我可以从 my 中的一个CheckboxSelectMultiple小部件中查看我的条目列表request.POST,但是当显式调用该参数时,它只返回我的第一个条目。该表单也不会验证我收到错误:

 File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\forms\forms.py", line 185, in is_valid
    return self.is_bound and not self.errors
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\forms\forms.py", line 180, in errors
    self.full_clean()
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\forms\forms.py", line 383, in full_clean
    self._post_clean()
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\forms\models.py", line 398, in _post_clean
    self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\forms\models.py", line 60, in construct_instance
    f.save_form_data(instance, cleaned_data[f.name])
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\db\models\fields\__init__.py", line 853, in save_form_data
    setattr(instance, self.name, data)
  File "C:\Users\lhepburn\Anaconda3\lib\site-packages\django\db\models\fields\related_descriptors.py", line 211, in __set__
    self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "['1', '2', '3']": "CanisterModel.test_cell" must be a "CellModel" instance.

所以如果我打印request.POST我得到:

<QueryDict: {'csrfmiddlewaretoken': ['9KwmPg1GzSXL98kjQbUHsvJGCIX3zNiBgqPbMPVtZtxYXKGnlZjreN9tDtDSdxiC'], 'test_cell': ['1', '2', '3'], 'canister_type': ['Total Hydrocarbons'], 'canister_change_date': ['07/07/2020'], 'time_field': ['12:30'], 'actual_conc': ['123']}>

如果我打印request.POST['test_cell'],我会得到:

'3'

如果我打印request.POST.getlist('test_cell'),我会得到:

['1', '2', '3']

更奇怪的是,如果我调试到我调用的断点并在调试终端中if update_canister_form.is_valid():运行它返回True并且脚本继续。update_canister_form.is_valid()

我想要的是

我想验证表单,而不必复制和操作 request.POST,只需将其传递到表单中并进行验证。

代码

形式

def queryset_to_choice(queryset):
    return [(x.id, x.__str__()) for x in queryset]

class UpdateCanisterForm(forms.ModelForm):

    test_cell = forms.MultipleChoiceField(
                choices=queryset_to_choice(CellModel.objects.all()),
                widget=forms.CheckboxSelectMultiple
            )
    canister_change_date = forms.DateTimeField(widget=forms.DateTimeInput(attrs={'class':'datepicker','style':'width:100px;'}))
    time_field = forms.TimeField(widget=forms.TimeInput(attrs={'style':'width:70px;','placeholder':'00:00'}))

    class Meta:
        model= CanisterModel
        fields = ('test_cell','canister_type','canister_change_date','actual_conc',)

楷模

class CanisterModel(models.Model):
    GASES = {'Carbon Monoxide':'Carbon Monoxide',
             'Carbon Dioxide':'Carbon Dioxide',
             'Methane':'Methane',
             'Total Hydrocarbons':'Total Hydrocarbons',
             'Nitric Oxide':'Nitric Oxide'}

    GASES = dict([(key, key) for key, value in GASES.items()]).items()

    test_cell = models.ForeignKey(CellModel, on_delete=models.CASCADE)
    canister_change_date = models.DateTimeField(blank=True, null=True) 
    updated_date = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    canister_type = models.CharField(max_length=50, choices=GASES, default='')
    actual_conc = models.DecimalField(max_digits=20, decimal_places=10)
    actual_conc_unit = models.CharField(max_length=10)
    sent_to_ocelot = models.BooleanField(default=False)
    objects = CanisterModelManager()
    history = HistoricalRecords()

class CellModel(models.Model):
    BOOKING_TYPES = {'Kanban':'Kanban',
                     'Scheduled':'Scheduled'}

    BOOKING_TYPES = dict([(key, key) for key, value in BOOKING_TYPES.items()]).items()

    cell = models.CharField(max_length=50, unique=True)
    description = models.CharField(max_length=100, null=True, blank=True)
    booking_type = models.CharField(max_length=50, choices=BOOKING_TYPES, default='')

    def __str__(self):
        return self.cell

看法

def post(self, request, pk=None, recordid=None, **kwargs):
    update_canister_form = UpdateCanisterForm(request.POST)
    if update_canister_form.is_valid():
        [...]

标签: pythondjango

解决方案


问题源于包含test_cell在表单元字段中。

class Meta:
        model= CanisterModel
        fields = ('test_cell','canister_type','canister_change_date','actual_conc',)
           #removed  --^

这将其从该模型字段的默认验证中删除。虽然我不明白这仍然无法验证。如果有人知道,请告诉我。


推荐阅读