首先,Django
ModelForm
是根据 Model
属性的类型去生成对应的 Field
的类型,如果是 String
,就是 TextInput
,列表就是 MultiChoice/MultiValue
,Password 就是 PasswordInput
,但是我博客里面新建/修改文章的 Tag
是以一个 , 来分隔的,就像下面这一样。
所以我需要用 TextInput
,并且 clean
直接不做任何处理直接返回,但是在 ArticleForm
的 clean_tag_list
和 save
这两个方法里面处理 Tag
def clean_tag_list(self):
'''根据,分隔'''
tags = self.cleaned_data.get('tag_list') or []
if tags:
if ' ' in tags:
raise forms.ValidationError('multi tag like "python,django"(Cannot contain Spaces)')
return tags.split(',')
return tags
def save(self, commit=True):
article = super(ArticleForm, self).save()
tags = self.cleaned_data.get('tag_list')
'''删除或者新建 Tag'''
if tags:
remove_tags = [t for t in article.tags.all() if t.name not in tags]
article.tags.remove(*remove_tags)
delete_no_article_tag(remove_tags)
for item in tags:
tag = Tag.objects.filter(name=item).first()
if not tag:
tag = Tag.objects.create(name=item)
article.tags.add(tag)
else:
remove_tags = article.tags.all()
article.tags.remove(*remove_tags) # remove all tags, if tag_list is empty
delete_no_article_tag(remove_tags)
return article