无法将 ModelForm 中的表单属性传递给模板

Posted

技术标签:

【中文标题】无法将 ModelForm 中的表单属性传递给模板【英文标题】:Can't passe form's attrs in ModelForm to Template 【发布时间】:2021-11-02 05:08:04 【问题描述】:

我正在尝试设置一个 ModelForm,但我没有得到我在模板中的表单中设置的属性。 另外,我想以 dd/mm/yyyy 格式获取日期输入, 这是我的模型

class Delivery(models.Model):
    user = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name=_("delivery_user"))
    full_name_reciever = models.CharField(_("Reciever Full Name"), max_length=50)
    pickup_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("pickup_address"))
    destination_address = models.CharField(max_length=250)
    destination_city = models.ForeignKey(City, on_delete=models.CASCADE, related_name=_("delivery_city"))
    destination_post_code = models.CharField(max_length=20)
    operation_date = models.DateField(
        _("desired pickup date"), auto_now=False, auto_now_add=False, blank=False, null=False
    )
    boxes_number = models.PositiveIntegerField(_("Number of Boxes"), default=1)
    boxes_wight = models.PositiveIntegerField(_("Boxes Wight"), default=1)
    boxes_volume = models.PositiveIntegerField(_("Boxes Volume"), default=0)
    document = models.FileField(
        help_text=_("Delivery Documets"),
        verbose_name=_("Delivery Certificates"),
        upload_to="documents/deliveries_documents/",
    )
    invoice = models.BooleanField(_("check if you want an invoice"), default=False)
    created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
    delivery_key = models.CharField(max_length=200)
    billing_status = models.BooleanField(default=False)
    delivery_status = models.BooleanField(default=False)

    class Meta:
        ordering = ("-created_at",)
        verbose_name = _("Delivery")
        verbose_name_plural = _("Deliveries")

    def __str__(self):
        return str(self.created_at)

ModelForm

class UserDeliveryForm(forms.ModelForm):
    class Meta:
        model = Delivery
        fields = [
            "full_name_reciever",
            "pickup_address",
            "destination_address",
            "destination_city",
            "destination_post_code",
            "operation_date",
            "boxes_number",
            "boxes_wight",
            "boxes_volume",
            "document",
            "invoice",
            "delivery_key",
            "billing_status",
            "delivery_status",
        ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["full_name_reciever"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "full name reciever "
        )
        self.fields["pickup_address"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "pickup address "
        )
        self.fields["destination_address"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "destination address"
        )
        self.fields["destination_city"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "destination city"
        )
        self.fields["destination_post_code"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "Post Code"
        )
        self.fields["operation_date"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "operation date"
        )
        self.fields["boxes_number"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "boxes number"
        )
        self.fields["boxes_wight"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "boxes wight"
        )
        self.fields["boxes_volume"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "boxes volume"
        )
        self.fields["document"].widget.attrs.update(
            "multiple": True, "class": "form-control mb-2 delivery-form", "Placeholder": "document"
        )
        self.fields["invoice"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "invoice"
        )
        self.fields["delivery_key"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "delivery key"
        )
        self.fields["billing_status"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "billing status"
        )
        self.fields["delivery_status"].widget.attrs.update(
            "class": "form-control mb-2 delivery-form", "Placeholder": "delivery status"
        )

还有我的观点

class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    model = Delivery
    fields = [
        "full_name_reciever",
        "pickup_address",
        "destination_address",
        "destination_city",
        "destination_post_code",
        "operation_date",
        "boxes_number",
        "boxes_wight",
        "boxes_volume",
        "document",
        "invoice",
        "delivery_key",
        "billing_status",
        "delivery_status",
    ]
    template_name = "deliveries/customer/edit_deliveries.html"
    success_url = reverse_lazy("account:dashboard")

    def test_func(self):
        return self.request.user.is_customer and self.request.user.is_active

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist("decument")
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        form.instance.user_id = self.request.user.id
        return super().form_valid(form)

我想在我的模板中使用日期格式 dd/mm/yyyy 获取日期纠察线,但是当我手动将输入类型指定为“日期”时我使用日期选择器获得格式 mm/dd/yyyy 的模板。 这是我使用的模板

% extends "../../account/sub_base.html" %
% load l10n %
% block title %Edit Delivery% endblock %

% block sub_content %
<div class=" col-lg-10 mx-auto">
  <h1 class="h3">Create/Edit Delivery</h1>
  <div>Add a new <b>Delivery</b> </div>
  <hr />
  <form name="delivery_form" class="delivery-form" method="post" enctype="multipart/form-data">
    % if form.errors %
    form.errors
    <div class="alert alert-primary" role="alert">
      Error: Please try again!
    </div>
    % endif %
    % csrf_token %
    <div class="form-group">
      <label class="small fw-bold"> form.full_name_reciever.label</label>
       form.full_name_reciever 
    </div>

    <div class="form-group">
      <label class="small fw-bold"> form.pickup_address.label</label>
      form.pickup_address  
    </div> 
      <div class="form-group">
        <label class="small fw-bold"> form.destination_address.label</label>
         form.destination_address </div>

    <div class="form-group">
      <label class="small fw-bold"> form.destination_city.label</label>
      form.destination_city </div>
     
      <div>
        <label class="small fw-bold"> form.destination_post_code.label</label>
         form.destination_post_code  
      </div> 
      % localize on %
      <div class="form-group">
        <label class="small fw-bold"> form.operation_date.label</label>
         form.operation_date  
      </div> 
      % endlocalize % 
      <div>
        <label class="small fw-bold"> form.boxes_number.label</label>
         form.boxes_number 
      </div>
      <div>
        <label class="small fw-bold"> form.boxes_wight.label</label>
         form.boxes_wight 
      </div>
      <div>
        <label class="small fw-bold"> form.boxes_volume.label</label>
         form.boxes_volume 
      </div>
      <div>
        <label class="small fw-bold"> form.document.label</label>
        <input type="file" multiple value= form.document > 
      </div>
      <div class="form-group form-check">
        <label class="small fw-bold"> form.invoice.label</label>
         form.invoice  
      </div>
      <div>
        <label class="small fw-bold"> form.delivery_key.label</label>
         form.delivery_key 
    </div>

    <div class="form-group form-check">
      <label class="small fw-bold"> form.delivery_status.label</label>
      <input type="checkbox" class="form-check-input" value= form.delivery_status  </div> 
    <button class="btn btn-primary btn-block py-2 mb-4 mt-4 fw-bold w-100" type="button" value="Submit"
        onclick="submitForm()">
      Add Delivery
      </button>
  </form>

</div>

<script>
  function submitForm() 
    var form = document.getElementsByName('delivery_form')[0];
    form.submit(); // Submit the form
    form.reset(); // Reset all form data
    return false; // Prevent page refresh
  
</script>
% endblock %

此外,即使我将表单设置为接受多个文件上传,我也需要在我的模板中手动设置它。还有在表单中的小部件设置中不起作用的 css class='form-control'

【问题讨论】:

【参考方案1】:

您可以在 ModelForm 类中使用流动代码:

operation_date = forms.DateField(widget=forms.DateInput(
    attrs="type": 'date', 'required': False, 'value': datetime.datetime.today().strftime('%Y-%d-%m')), label=_("Date"))

【讨论】:

【参考方案2】:

我解决了这个问题,我发现我没有将 Mofelform 分配给 Modelview 的上下文数据。 这是 ModelView

class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    model = Delivery
    form_class = UserDeliveryForm
    template_name = "deliveries/customer/edit_deliveries.html"
    success_url = reverse_lazy("account:dashboard")

    def test_func(self):
        return self.request.user.is_customer and self.request.user.is_active

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist("decument")
        if form.is_valid():
            for f in files:
                f.save()
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        form.instance.user_id = self.request.user.id
        return super().form_valid(form)

这是我得到的结果:

【讨论】:

以上是关于无法将 ModelForm 中的表单属性传递给模板的主要内容,如果未能解决你的问题,请参考以下文章

将 Laravel 中的表单值传递给 Blade 模板

使用 Django,如何在模板中动态设置 ModelForm 字段值?

Django如何将外键传递给ModelForm字段

Flask / WTF表单将变量传递给模板会产生500错误,表单未定义

将 Django 表单传递给模板标签

如何将初始表单值传递给 Vue.js 中的子组件?