小部件形式的多对多字段

Many to many fields in widget form

我在表单小部件中显示多对多字段时遇到问题。 类别未显示在模板中。 标题没问题(显示)但类别不正确 - 类别为空。 我该怎么做才能在带有多选复选框的模板表单中显示多对多字段? 为什么我无法以小部件形式显示文章类别?

MODELS.py

文章型号:

class Article(Created, HitCountMixin):
    title = models.CharField(max_length=120)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    category = models.ManyToManyField(ArticleCategory, related_name='articles')

类别模型:

class ArticleCategory(Created):
    category_name = models.CharField(max_length=128)
    slug = models.SlugField(null=False, unique=False)

观看次数:

class UpdateArticleView(LoginRequiredMixin, UpdateView):
    template_name = 'news/update_article.html'
    form_class = EditArticleForm
    model = Article

    def get_success_url(self):
        pk = self.kwargs["pk"]
        slug = self.kwargs['slug']
        return reverse_lazy("news:article_detail", kwargs={'pk': pk, 'slug': slug})

FORMS.py

class AddArticleForm(forms.ModelForm):

title = forms.CharField(
    label="Tytuł",
    max_length=120,
    help_text="Tytuł newsa",
    widget=forms.TextInput(attrs={"class": "form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded"}),
    required=True,
)


category = forms.MultipleChoiceField(
    widget=forms.CheckboxSelectMultiple,
)

在我的 HTML 模板中:

    <form method="post" enctype='multipart/form-data'>
        {% csrf_token %}
        {{ form.media }}
        {#        {%  crispy form %}#}
        {{ form|crispy }}
        <button type="submit" class="btn btn-outline-primary">EDYTUJ NEWS</button>
    </form>

你的form_class在你看来是一个EditArticleForm,所以你要注意使用正确的形式。

ManyToManyField 的表单域通常是 ModelMultipleChoiceField [Django-doc],但无论如何都没有必要指定表单域。您可以使用 widgets 选项:

class <b>EditArticleForm</b>(forms.ModelForm):
    title = forms.CharField(
        label='Tytuł',
        max_length=120,
        help_text='Tytuł newsa',
        widget=forms.TextInput(
            attrs={'class': 'form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded'}
        ),
        required=True,
    )


    class Meta:
        model = Article
        <b>widgets</b> = {
            'category': <b>forms.CheckboxSelectMultiple</b>
        }

您可以通过以下方式自定义标签:

class EditArticleForm(forms.ModelForm):
    title = forms.CharField(
        label='Tytuł',
        max_length=120,
        help_text='Tytuł newsa',
        widget=forms.TextInput(
            attrs={'class': 'form-control form-control-lg pr-5 shadow p-1 mb-1 bg-white rounded'}
        ),
        required=True,
    )


    class Meta:
        model = Article
        widgets = {
            'category': forms.CheckboxSelectMultiple
        }
        <b>labels</b> = {
            'category': 'label of category'
        }