使用 Initial 预填充 django 表单不起作用

Pre populating a django form using Initial not working

我正在尝试通过预填充 'template_name' 字段来保存模型。根据 django 文档和其他线程,很明显初始参数应该有效,但我不能让它适用于我的代码。我收到 template_name 字段为空的错误。任何关于我缺少什么的帮助以及任何其他方法都会很棒。这是代码

models.py

class TemplateNameModel(models.Model):
    "Model to add the template name"
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    tna_template_name = models.CharField(verbose_name="Template name",max_length = 128, unique = True,
                                    null = False, blank = False, help_text="please enter name of the new tna template")
    description = models.CharField(verbose_name="template description", max_length = 256,
                                    null = True, blank = True, help_text ="Please enter the description(optional)")
    created_by = models.TextField(verbose_name="Template created by", max_length= 128,
                                    null = False, blank = False,help_text ="Please enter the name of creator")
    date_created = models.DateTimeField(auto_created= True, null = True, blank = True)
    is_active = models.BooleanField(verbose_name="Template status",null = False , blank= False)

    def __str__(self):
        return self.tna_template_name

class TnaTemplateModel(models.Model):
    id = models.AutoField(primary_key=True, editable=False)
    template_name = models.ForeignKey(TemplateNameModel, verbose_name="template name", null=False,
                                        blank=False, on_delete=models.CASCADE, help_text="Select the template")
    process_name = models.ForeignKey(ProcessModel, verbose_name="process name", null=False,
                                        blank=False, on_delete=models.CASCADE, help_text="Select the process")
    sequence = models.IntegerField(verbose_name="Process Sequence",null = False,blank = False)
    is_base = models.BooleanField()
    formula = models.IntegerField(verbose_name="Formula", null= True,blank = True)
    remarks = models.CharField(verbose_name="Process remarks", null= True, blank = True,max_length= 300)
    class Meta:
        unique_together = ["template_name", "process_name"]
    
    def __str__(self):
        return str(self.template_name)

forms.py

class ProcessModelformNew(forms.ModelForm):

    class Meta:
        model = TnaTemplateModel
        fields =('__all__')

views.py

def processcreatenew(request,pk):
    template_name = TemplateNameModel.objects.get(id=pk)
    if request.method == 'POST':
        form = ProcessModelformNew(request.POST)
        if form.is_valid():
            form.save()
    else:
        data = {'template_name': template_name}
        form = ProcessModelformNew(initial= data)
    return render (request,"tna/template_tna/baseprocessmodel_create.html",{'form':form})

Html 模板

<form role="form" method="POST" enctype="multipart/form-data">
                {% csrf_token %}
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-6 col-sm-12">
                            <!-- text input -->
                            <div class="form-group">
                                {{form.process_name|as_crispy_field}}
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-6 col-sm-12">
                            <!-- text input -->
                            <div class="form-group">
                                {{form.sequence|as_crispy_field}}
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-6 col-sm-12">
                            <!-- text input -->
                            <div class="form-group">
                                {{form.is_base|as_crispy_field}}
                            </div>
                        </div>
                        <div class="col-md-6 col-sm-12">
                            <!-- text input -->
                            <div class="form-group">
                                {{form.formula|as_crispy_field}}
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-md-6 col-sm-12">
                            <!-- text input -->
                            <div class="form-group">
                                {{form.remarks|as_crispy_field}}
                            </div>
                        </div>
                    </div>
                    
                </div>
                <!-- /.card-body -->
                <div class="card-footer">
                    <button type="submit" class="btn btn-primary">Save</button>
                </div>
            </form>

forms.py

  def __init__(self, *args, **kwargs):
     template_name = kwargs.pop('template_name',None)
     self.fields['template_name']= template_name

views.py

在您的模型表单中

def processcreatenew(request,pk):
   template_name = TemplateNameModel.objects.get(id=pk)
   if request.method == 'POST':
      form = ProcessModelformNew(request.POST or None, template_name= template_name)

你必须执行这样的操作

第一种方法

  • 在您的 HTML 中包含 {{ form.template_name }} 即使您不想编辑它,也只是将其隐藏

第二种方法

  • 在你的 forms.py 中你可以把 exclude = ['template_name'] 代替 fields =('__all__') 这样它就不再需要了,然后在 views.py
    obj = form.save(commit=False)
    obj.template_name = template_name
    obj.save()
  • 所以如果你不想在 HTML 中包含 template_name 第二种方法很好,你也不必启动表单

您需要在模板中呈现 template_name 字段,以便将所选值传递到 POST 数据中。

{{ form.template_name }}

我怀疑您不想显示该字段,您应该用 forms.HiddenInput 覆盖它的小部件,这样用户就看不到它了

class ProcessModelformNew(forms.ModelForm):

    class Meta:
        model = TnaTemplateModel
        fields = '__all__'
        widgets = {'template_name': forms.HiddenInput()}