简体   繁体   English

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

[英]Django-taggit tag value retrieval and formatting failing

I am trying to implement a tagging process for profiles so you can add your hobbies for example.我正在尝试为个人资料实施标记过程,以便您可以添加您的爱好。 I have chosen django-taggit as it seemed quite simple and does what I need it to, plus don't really know how to do it myself from scratch.我选择了 django-taggit,因为它看起来很简单,而且可以做我需要做的事情,而且我自己也不知道如何从头开始。 I have managed to make it work to some extent but I am having issues with 3 things:我已经设法使其在某种程度上起作用,但我遇到了 3 件事:

  1. Not really sure what's the best way to control the form field for these tags as I generate the form automatically with widget adjustments in meta function of the form, but it might work fine after resolving the below two issues.不确定控制这些标签的表单字段的最佳方法是什么,因为我通过表单元功能中的小部件调整自动生成表单,但在解决以下两个问题后它可能会正常工作。
  2. When there is no data for the field hobbies (tags) the field gets populated with a single tag of value "[]" as per below image.当没有字段爱好(标签)的数据时,该字段将填充一个值为“[]”的单个标签,如下图所示。

在此处输入图片说明

  1. When I add a tag of "music" and submit the form after I reload the page I get this "[]" as per image.当我添加“音乐”标签并在我重新加载页面后提交表单时,我会根据图像得到这个“[]”。 I assumed this will be dealt with by the library, but I cannot see another similar scenario online.我认为这将由图书馆处理,但我在网上看不到另一个类似的场景。

在此处输入图片说明

When I try adding another tag of "games" and save and reload, the below happens.当我尝试添加另一个“游戏”标签并保存并重新加载时,会发生以下情况。 The initial value gets wrapped again.初始值再次被包装。

在此处输入图片说明

My model is:我的模型是:

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

My form is:我的表格是:

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

My view function is:我的视图功能是:

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()

Using:使用:

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

So after quite a few (hundreds) of tests, I finally narrowed down where the issue was and tried to go around it with successful result.因此,经过相当多(数百次)测试后,我终于缩小了问题的范围,并试图以成功的结果解决它。 It seems the data got amended into tag objects through tagsinput library I was using.似乎数据通过我使用的标签输入库修改为标签对象。 Only when the "data-role" was specified as "tagsinput" in the forms.py the data would already come to html side as those objects and be shown incorrectly.只有当在 forms.py 中将“数据角色”指定为“标签输入”时,数据才会作为这些对象进入 html 端并显示不正确。 So instead I wanted to keep the data clean and only apply data-role='tagsinput' in the end for visual aspect, which I did using:所以相反,我想保持数据干净,最后只在视觉方面应用 data-role='tagsinput' ,我使用了:

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

And that resulted in the below.这导致了以下情况。 Maybe there are better ways to do this, I'm not sure, but it's a pretty clean solution.也许有更好的方法可以做到这一点,我不确定,但这是一个非常干净的解决方案。 Share your alternatives.分享您的替代方案。

在此处输入图片说明

I had this exact same problem.我有这个完全相同的问题。

One solution is to apply the data-role="tagsinput" AFTER you turn a list of tags into a comma-separated string for the form.一种解决方案是在将标签列表转换为表单的逗号分隔字符串应用data-role="tagsinput"

Here is that solution:这是解决方案:

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"

Output:输出:

腋窝报价

As you can see, there's a problem with quotes appearing around tags that are multi-word.如您所见,多词标签周围出现引号存在问题 It also causes new tags with quotes to be saved to the database.它还会使带引号的新标签保存到数据库中。

引用的腋窝

If double-quotes didn't appear around multi-word phrases, this would be the most elegant solution.如果双引号没有出现在多词短语周围,这将是最优雅的解决方案。 If someone solves this in the future, drop a note!如果将来有人解决了这个问题,请留言!

My template is this:我的模板是这样的:

  <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>

I know I can use a template tag to strip the extra quotes from the tag field itself, but then I'd have to go through and create all the form fields manually just to set the tags template tag.我知道我可以使用模板标签从标签字段本身中去除额外的引号,但是我必须手动创建所有表单字段才能设置标签模板标签。

For the time being, my solution is to simply use Javascript and just modify the Meta widgets section of the form.目前,我的解决方案是简单地使用 Javascript 并修改表单的 Meta 小部件部分。

FINAL ANSWER (for now):最终答案(目前):

forms.py表格.py

class CourseManageDetailsForm(forms.ModelForm):

    class Meta:
        model = MyModel

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

custom.js - put this script on the page that loads the form. 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);
}

So all we're doing is modifying the front-end presentation, and leaving all the backend internal forms functionality untouched.因此,我们所做的只是修改前端表示,并保持所有后端内部表单功能不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM