Экземпляры тегов через django-taggit не отображаются так, как ожидается, в форме сообщения об обновлении

{{ form.tags | as_crispy_field }} при получении экземпляра вопроса отображается не так, как ожидалось. Тот же синтаксис crispy forms работает и отображается идеально при создании начального поста

Нажатие кнопки Submit приводит к ошибке Server 500. Результаты тестирования задокументированы в строке:

<!-- templates/update_question.html -->
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}

{% block extra_head %}
<!-- django-quill-editor Media -->
{% include 'django_quill/media.html' %}
{% endblock %}

{% block content %}

<main class="flex-shrink-0 main-bg">
    <div class="container-question my-5">
[...]
        <form id="standards-form" method="post" action="{% url 'question_update' slug=question.slug %}">
            {% csrf_token %}
        [...]
            
            <h2 class="text-center">Subject line</h2>
            {{ form.subject | as_crispy_field }} <!-- rendering as expected-->

            
            <br>
            <h2 class="text-center">Details</h2>
            {{ form.content | as_crispy_field }} <!-- rendering as expected-->
            <br>
            <h2 class="text-center">Tags</h2>
            <div class="tag-input">
                <div class="input">
                    <div>
                        <i class="fa fa-tags"></i>
                        {{ form.tags | as_crispy_field }} <!--not rendering as expected: reading as [<Tag: tag1>, <Tag: tag2>, <Tag: tag3>]. Expecting tag1 tag2 tag3 to be retrieved from django-taggit's TaggableManager-->
                    </div>
                </div>
                <div class="tag-list mb-4"></div>
            </div>
            <button type="submit" class="btn btn-primary " id="question-submit">Submit</button>
        </form>
        
    </div>

</main>

{% endblock %}

Шаги отладки

форма обрабатывается в этом классе Я пробовал печатать журналы и перемещать функцию init в начало.

# main_forum/forms/question_form.py

# This file contains the form for the Question model. The QuestionForm class will be used to create and update questions in the forum.

from django import forms
from django.contrib.auth.models import User
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from ..models import Question, Answer
from django_quill.forms import QuillFormField
from taggit.forms import TagField
from django.contrib.auth.forms import PasswordChangeForm


class QuestionForm(forms.ModelForm):
    [...]
    tags = forms.CharField(required=False)

    class Meta:
        model = Question  # Specifies the model in models.py associated with this form
        fields = ['subject', 'content', 'tags']

    def __init__(self, *args, **kwargs):
        """
        This is for checking if the form is bound to an existing instance, i.e. if the form is being used to update an existing question.
        """
        super(QuestionForm, self).__init__(*args, **kwargs)
        [...]

        if self.instance.pk: 
            self.fields['tags'].initial = ' '.join(tag.name for tag in self.instance.tags.all()) # Pre-populate the tags field with the existing tags
            print('tags initial:', self.fields['tags'].initial) # PASS. prints as  tags initial: tag1 tag2 tag3

    [...]

    def clean_tags(self):
        tags = self.cleaned_data.get('tags', '')
        return tags

    def save(self, *args, **kwargs):
        instance = super(QuestionForm, self).save(commit=False)
        instance.save()

        # Handling tags here
        tags = self.cleaned_data.get('tags', '')
        tag_names = tags.split()
        print('tag_names after tag.split', tag_names) # expecting ['tag1', 'tag2', 'tag3'] in order to be saved correctly etc. PASS
        instance.tags.clear()

        for tag_name in tag_names:
            instance.tags.add(tag_name.strip())  # Ensure tag is stripped of extra whitespace

        print('instance.tags.all:', instance.tags.all()) # PASS <QuerySet [<Tag: tag1>, <Tag: tag2>, <Tag: tag3>]> etc.

        if self.instance.pk:
            # If this is an update, save the instance again
            instance.save()  # Save the instance again to save the many-to-many relationships
            print('instance saved:', instance) # testing: leads to server 500 error

        return instance



Похоже, что лучшее решение, которое я могу найти, это замена {{ form.tags | as_crispy_field }} на пользовательский ввод, который использует {{ question.tags.all|join:' ' }}:

<input type="text" name="tags" id="id_tags id_tags_update" value="{{ question.tags.all|join:' ' }}" /> <!-- this correctly renders the tags as tag1 tag2 tag3 etc.-->
Вернуться на верх