已解决:如何在 Django 中的表单错误中重新显示带有选定值的表单集和 Select2 字段

Posted

技术标签:

【中文标题】已解决:如何在 Django 中的表单错误中重新显示带有选定值的表单集和 Select2 字段【英文标题】:Resolved: How to re-display formset & Select2 field with selected value on form error in Django 【发布时间】:2021-06-15 05:18:51 【问题描述】:

在搜索了几天并尝试了不同的选项后,我最终决定发布问题和问题。

我有一个包含一个表单和 2 个不同表单集的模板。

其中一个表单集使用带有 GenericForeignKey 的中间模型,该模型将引用其他两个模型。 对于表单集,我使用了一个内联表单集并添加了一个与 Select2 一起使用的 CharField 来进行 ajax 调用以检查其他两个模型。 ajax 调用返回的值将是一个带有 3 个键/值对的 json/dict。

我遇到的问题是,当模板提交时出现错误,当模板再次出现时,如何重新显示在 Select2 CharField 中输入的值?

值在 self.data 中并被发送回模板。 但是,到目前为止,我尝试过的所有操作都不会重新显示带有先前选择的值或提交的值的 select2 字段。

提交的值以 json/dict、key/value、form.fieldname.value 下的格式返回到模板,但我不确定如何使用它来重新填充 select2 字段。

感谢任何建议或链接。如果有其他设置方法,我很想知道。

谢谢。

更新:2021-03-18

以下是各种文件中的所有相关部分。

models.py

class SiteDomain(models.Model):
    website = models.ForeignKey(
        WebSite,
        on_delete=models.CASCADE,
    )
    domain_model = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE,
        help_text=(
            "The model that the website entry is related to. eg: Domain or SubDomain"
        ),
    )
    object_id = models.PositiveIntegerField(
        help_text="The ID of the model object the entry is related to."
    )
    content_object = GenericForeignKey("domain_model", "object_id")
    content_object.short_description = "Domain Name:"

views.py

class AddWebsite(View):
    def get(self, request, *args, **kwargs):

        domain_formset = inlineformset_factory(
            WebSite,
            SiteDomain,
            formset=SiteDomainInlineFormSet,
            fields=(),
            extra=3,
        )

forms.py

class SiteDomainInlineFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        self.account = kwargs.pop('account', None)
        super(SiteDomainInlineFormSet, self).__init__(*args, **kwargs)

    def add_fields(self, form, index):
        super().add_fields(form, index)

        form.fields["domain_name"] = forms.CharField(
            max_length=255,
            widget=forms.Select(),
            required=False,
        )

模板

<script type="text/javascript">
function s2search() 
    $('.domain-lookup-ajax').select2(
        width: 'style',
        ajax: 
            url: "% url 'accounts_ajax:website_domain_lookup' %",
            dataType: 'json',
            delay: 250,
            data: function (params) 
                var query = 
                    term: params.term,
                    acct_id: ' account.id ',
                
                return query;
            ,
            processResults: function (data, params) 
                return 
                    results: data,
                ;
            ,
            cache: true
        ,
        placeholder: 'Enter at least 2 characters for search.',
        minimumInputLength: 2,
    );

</script>

<form action="" method="post">
    % csrf_token %

     domain_formset.management_form 
     app_formset.management_form 

        % for form in domain_formset %
            <div class="domainfieldWrapper" id="row_ forloop.counter0 ">
                <select id="id_dform- forloop.counter0 -domain_name" class="domain_name domain-lookup-ajax" name="dform- forloop.counter0 -domain_name"></select>

                <button id="id_dform- forloop.counter0 -button" class="button" type="button" onclick="clearSelect('id_dform- forloop.counter0 -domain_name')">Clear</button>
            </div>
        % endfor %

</form>

ajax 调用将返回如下内容:

"model_id":"74", "domain_id":"177", "name":"alfa.first-example.com"

附注: 我还测试了第二个表单集中的 select2 字段,如果有任何表单错误,则在重新加载模板时也不会重新填充它。我有点预料到,因为它基本上使用相同的设置,除了 ajax 调用返回的值用于普通的 ModelChoiceField。

【问题讨论】:

显示您已经尝试过的代码。 @NKSM 请查看更新后的帖子 【参考方案1】:

结合使用https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2、js 和 Django 模板标签,我能够得到适合我的东西。

【讨论】:

以上是关于已解决:如何在 Django 中的表单错误中重新显示带有选定值的表单集和 Select2 字段的主要内容,如果未能解决你的问题,请参考以下文章

刷新时重新提交的django表单

Django:在管理表单之外使用ForeignKeyRawIdWidget

引导弹出窗口中的 Django 登录表单

使用Ajax验证并提交Django表单(django-crispy-forms)

我可以更改表单小部件类而不在 Django 中明确重新定义它吗?

django - 表单中的动态选择字段