Django-taggit 标签值检索和格式化失败

Django-taggit tag value retrieval and formatting failing

我正在尝试为配置文件实施标记过程,以便您可以添加您的爱好等。 我选择了 django-taggit,因为它看起来很简单并且可以满足我的需要,而且我自己也不知道如何从头开始。 我已经设法让它在某种程度上发挥作用,但我遇到了 3 件事的问题:

  1. 不太确定控制这些标签的表单字段的最佳方法是什么,因为我会自动生成表单,并在表单的元函数中进行小部件调整,但在解决以下两个问题后它可能会正常工作。
  2. 当没有字段爱好(标签)的数据时,字段将填充一个值为“[]”的标签,如下图所示。

  1. 当我添加 "music" 的标签并在重新加载页面后提交表单时,我得到了这个“[]”,如图所示。我以为这将由图书馆处理,但我在网上看不到另一个类似的情况。

当我尝试添加 "games" 的另一个标签并保存并重新加载时,会发生以下情况。初始值再次换行。

我的模型是:

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
hobbies = TaggableManager()

我的表格是:

class UserProfileForm(forms.ModelForm):

    class Meta:
        model = UserProfile
        fields = ['hobbies',]

    def __init__(self, *args, **kwargs):
      super(UserProfileForm, self).__init__(*args,**kwargs)
      self.fields['hobbies'].widget = forms.TextInput()
      self.fields['hobbies'].widget.attrs['data-role'] = "tagsinput"
      self.fields['hobbies'].widget.attrs['class'] = "form-control"
      self.fields['hobbies'].required = False

我的视图函数是:

if request.method == 'POST':
        user_profile = UserProfile.objects.get(user=request.user)
        form = UserProfileForm(request.POST, instance=user_profile)
        print(form)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            print("Form valid")
            form.save_m2m()

使用:

<script src="/static/js/tagsinput.js"></script>
<link rel="stylesheet" href="{% static 'css/tagsinput.css' %}" />

因此,经过多次(数百次)测试后,我终于缩小了问题所在的范围,并尝试绕过它并取得了成功。 似乎通过我使用的 tagsinput 库将数据修改为标签对象。只有当 "data-role" 在 forms.py 中指定为 "tagsinput" 时,数据才会作为那些对象到达 html 端并且显示不正确。因此,我想保持数据干净,最后只在视觉方面应用 data-role='tagsinput',我确实使用了:

var hobbiesTags = document.getElementById("id_hobbies");
  if(hobbiesTags){
  var att = document.createAttribute("data-role");
  att.value = "tagsinput";
  hobbiesTags.setAttributeNode(att);
  };

结果如下。也许有更好的方法来做到这一点,我不确定,但这是一个非常干净的解决方案。分享您的选择。

我遇到了完全相同的问题。

一个解决方案是应用 data-role="tagsinput" AFTER 将标签列表转换为表单的逗号分隔字符串。

这是解决方案:

class MyModelForm(forms.ModelForm):

    class Meta:
        model = MyModel

    def __init__(self, **kwargs):
        self.fields['tags'].widget.attrs['value'] = ", ".join(list(self.instance.tags.names()))
        self.fields['tags'].widget.attrs['data-role'] = "tagsinput"

输出:

如您所见, 出现在多词标签周围的引号存在问题。它还会导致将带有引号的新标签保存到数据库中。

如果双引号没有出现在多词短语周围,这将是最优雅的解决方案。如果以后有人解决了这个问题,请留言!

我的模板是这样的:

  <div class="m-3 p-3 border">
    <form method="POST" enctype="multipart/form-data">
      {% csrf_token %}
      {{ form|crispy }}
      <button class="btn btn-primary" type="submit">Save Form</button>
    </form>
  </div>

我知道我可以使用模板标签从标签字段本身去除额外的引号,但我必须手动创建所有表单字段才能设置标签模板标签。

目前,我的解决方案是简单地使用 Javascript 并修改表单的元小部件部分。

最终答案(目前):

forms.py

class MyModelForm(forms.ModelForm):

    class Meta:
        model = MyModel

        widgets = {
            'tags': forms.TextInput(attrs={
                "data-role": "tagsinput",
            })
        }

custom.js - 将此脚本放在加载表单的页面上。

document.addEventListener("DOMContentLoaded", function(event) {
    let tags_input = document.querySelector('#id_tags');
    let tags_input_value = tags_input.value;
    let new_value = [...tags_input_value.matchAll(/<Tag:\s*([\w\s]+)>/g)].map(([, m]) => m).join(', ')
    tags_input.setAttribute('value', new_value);
}

所以我们所做的只是修改前端表示,并保持所有后端内部表单功能不变。