Django 表单未填充 POST 数据

问题描述 投票:0回答:2

底部的解决方案

问题: Django 表单填充了对象列表,而不是

摘要:我有 2 个模型实体中断BreaksEntities 模型上的 entity_id(不是 PK)具有 FK 关系。

我想为Breaks的所有字段生成一个空表单。生成基本表单会填充所有空字段,但对于 FK,它会生成 Entities 表的所有 objects 的下拉列表。这没有帮助,所以我在下面的 ModelForm 中排除了它,并尝试用 Entities 表的所有 entity_ids 列表替换。此表单按预期呈现。

class BreakForm(ModelForm):   
    class Meta:
        model = Breaks
        #fields = '__all__'
        exclude = ('entity',)
    
    def __init__(self, *args, **kwargs):        
        super(BreakForm, self).__init__(*args, **kwargs)         
        self.fields['entity_id'] = ModelChoiceField(queryset=Entities.objects.all().values_list('entity_id', flat=True))    

下面的FormView就是URL调用的cbv。如下所示,如果我填充表单,并且对于 FK 列 entity_id 选择其中一个值,则表单将不会提交。表单模板上的该字段将显示以下消息 选择有效选项。该选择不是可用的选择之一

class ContactFormView(FormView):
    template_name = "breaks/test/breaks_form.html"
    form_class = BreakForm

我最初的想法是该字段的数据类型(字符串/整数)错误,或者 Django 需要 Entities 表中的行的 PK(无论出于何种原因)。

因此,我向 FormView 添加了一个 post 函数,并且可以看到 request.body 已正确填充。但是我不知道如何将其填充到 ModelForm 中并保存到数据库,或克服上述问题。

附录:

添加的型号如下:

class Entity(models.Model):
    pk_securities = models.AutoField(primary_key=True)
    entity_id = models.CharField(unique=True)
    entity_description = models.CharField(blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'entities'
    
    
class Breaks(models.Model):
    pk_break = models.AutoField(primary_key=True)
    date = models.DateField(blank=True, null=True)    
    entity = models.ForeignKey(Entity, on_delete= models.CASCADE, to_field='entity_id')  
    commentary = models.CharField(blank=True, null=True)
    active = models.BooleanField()

    def get_absolute_url(self):
        return reverse(
            "item-update", args=[str(self.pk_break)]
        )

    def __str__(self):
        return f"{self.pk_break}"

    class Meta:
        managed = False
        db_table = 'breaks'

解决方案

首先,我通过将以下内容添加到实体模型类来实现此功能。然而我不喜欢这个,因为它会在其他地方产生后果。

def __str__(self):
        return f"{self.entity_id}"

我在主题上找到了这个SO线程。接受的答案非常棒,对其的评论也很有帮助。 解决方案是子类化

ModelChoiceField
并覆盖
label_from_instance

class EntityChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.entity_id
python django django-models django-views django-forms
2个回答
1
投票

我认为你的问题有两个,首先是没有正确渲染下拉列表,第二是表单没有保存。对于第一个问题,您不需要在

ModelChoiceField
查询集中进行任何更改,而是添加
to_field_name
:

class BreakForm(ModelForm):   
    class Meta:
        model = Breaks
        #fields = '__all__'
    
    def __init__(self, *args, **kwargs):        
        super(BreakForm, self).__init__(*args, **kwargs)         
        self.fields['entity_id'] = ModelChoiceField(queryset=Entities.objects.all(), to_field_name='entity_id')

其次,如果你想保存表单,不要使用FormView,而是使用

CreateView
:

class ContactFormView(CreateView):
    template_name = "breaks/test/breaks_form.html"
    form_class = BreakForm
    model = Breaks

0
投票

解决方案

首先,我通过将以下内容添加到实体模型类来实现此功能。然而我不喜欢这个,因为它会在其他地方产生后果。

def __str__(self):
        return f"{self.entity_id}"

我发现了这个主题的主题。接受的答案非常棒,对其的评论也很有帮助。解决方案是子类化 ModelChoiceField 并覆盖 label_from_instance

class EntityChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.entity_id
© www.soinside.com 2019 - 2024. All rights reserved.