Django-taggit 标签值检索和格式化失败
Django-taggit tag value retrieval and formatting failing
我正在尝试为配置文件实施标记过程,以便您可以添加您的爱好等。
我选择了 django-taggit,因为它看起来很简单并且可以满足我的需要,而且我自己也不知道如何从头开始。
我已经设法让它在某种程度上发挥作用,但我遇到了 3 件事的问题:
- 不太确定控制这些标签的表单字段的最佳方法是什么,因为我会自动生成表单,并在表单的元函数中进行小部件调整,但在解决以下两个问题后它可能会正常工作。
- 当没有字段爱好(标签)的数据时,字段将填充一个值为“[]”的标签,如下图所示。
- 当我添加 "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);
}
所以我们所做的只是修改前端表示,并保持所有后端内部表单功能不变。
我正在尝试为配置文件实施标记过程,以便您可以添加您的爱好等。 我选择了 django-taggit,因为它看起来很简单并且可以满足我的需要,而且我自己也不知道如何从头开始。 我已经设法让它在某种程度上发挥作用,但我遇到了 3 件事的问题:
- 不太确定控制这些标签的表单字段的最佳方法是什么,因为我会自动生成表单,并在表单的元函数中进行小部件调整,但在解决以下两个问题后它可能会正常工作。
- 当没有字段爱好(标签)的数据时,字段将填充一个值为“[]”的标签,如下图所示。
- 当我添加 "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);
}
所以我们所做的只是修改前端表示,并保持所有后端内部表单功能不变。