Django:根据 select 下拉列表和 Jquery/Ajax 动态创建复选框?

Django: Create check boxes dynamically based on select dropdown with Jquery/Ajax?

我正在使用 Django Crispy Forms,在我的创建表单中,我希望我的用户在 select 下拉列表中选择一个类别,然后我想获取与该类别并在下面的复选框中显示所有功能。我认为 ajax/Jquery 是有道理的,所以我想出了以下内容:

我的看法:

def show_category_feature_set(request):

    category_id = request.GET.get('category')
    category = Category.objects.get(id=category_id)
    features = category.features.all().values('name', 'id')
    response_data = {}
    try:
        response_data['features'] = list(features)
    except:
        response_data['error'] = "Sorry, couldn\'t load any features"
    return JsonResponse(response_data)

我的模特:

class Feature(models.Model):
    name = models.CharField(max_length=100, blank=False)

class Category(models.Model):
    name = models.CharField(max_length=50, blank=False)
    slug = models.SlugField(unique=True)
    features = models.ManyToManyField(Feature, through='FeatureCategorization' )

class FeatureCategorization(models.Model):
    category = models.ForeignKey(Category)
    feature = models.ForeignKey(Feature)

这是我的表格:

class ListingForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ListingForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'listing'
        self.helper.form_show_errors = True
        self.helper.form_method = 'post'
        self.helper.form_action = 'submit'
        self.helper.add_input(Submit('submit', 'Submit'))

    class Meta:
        model = Listing
        fields = ['title', 'event_types', 'category', 'features', 'description', 'blog_url', 'website', 'pricing_page']

        widgets = {
            'event_types': forms.CheckboxSelectMultiple(),
            'features': forms.CheckboxSelectMultiple()
        }

这是我的 Django Crispy 表单(模型表单)生成的 html。我需要动态创建这个块,所以下面的复选框需要根据前面的 select 显示。

<div class="form-group" id="div_id_features">
    <label class="control-label requiredField" for="id_features_0">Features<span class="asteriskField">*</span></label>
    <div class="controls" id="listing">
        <div class="checkbox">
            <label class=""><input id="id_features_1" name="features" type="checkbox" value="10">Online Registration</label>
        </div>
        <div class="checkbox">
            <label class=""><input id="id_features_2" name="features" type="checkbox" value="11">PCI Compliance</label>
        </div>
    </div>
</div>

这里是 AJAX,它可以正确执行所有操作,但不会生成正确的 HTML。

$( "#id_category" ).change(function () {
  var category = $( this ).val();

  $.ajax({
    url: '/ajax/category_features/',
    data: {
      'category': category
    },
    dataType: 'json',
    success: function ( response_data ) {
      $("#div_id_features").empty().append(response_data.features.map((feature) => {
        return  $('<input >', {
            type : 'checkbox',
            id: 'id_features_' + feature.id,
            name: 'features',
            value: feature.id,
        }).wrap("<label > </label>").text(feature.name);
      }));
    }
  });
});

以上生成以下内容(它基本上显示了两个空复选框,未格式化,未标记)。

<div id="div_id_features" class="form-group">
    <input type="checkbox" id="id_features_10" name="features" value="10">
    <input type="checkbox" id="id_features_11" name="features" value="11">
</div>

我真的不知道我是否正确地解决了这个问题。根据之前的 select 下拉列表动态创建复选框的最简单方法是什么?我的 Jquery 怎么了?您可能会说,我是初学者。你们会怎么做?我的方法有什么问题?任何帮助将不胜感激。

这就是 .wrap 的工作原理,看起来元素必须在 DOM 中才能工作,但无论如何,根本不需要包装它,你可以在地图中创建任何你想要的东西。

这里有一个例子 - https://jsfiddle.net/oborudko/eo5x0unr/

  $('#features').empty().append(features[$(this).val()].map(feature => $('<div class="checkbox"><label>' + 
    '<input type="checkbox" name="features[]" value="' + feature.id + '"/>' + feature.name +
    '</label>')
  ));
});