Skip to content

Instantly share code, notes, and snippets.

@AnyISalIn
Created August 25, 2017 06:34
Show Gist options
  • Save AnyISalIn/cde10be43469ea51521cbb44fb8a21b9 to your computer and use it in GitHub Desktop.
Save AnyISalIn/cde10be43469ea51521cbb44fb8a21b9 to your computer and use it in GitHub Desktop.

为什么要自定义 Field 类型

首先,Django ModelForm 是根据 Model 属性的类型去生成对应的 Field 的类型,如果是 String,就是 TextInput,列表就是 MultiChoice/MultiValue,Password 就是 PasswordInput,但是我博客里面新建/修改文章的 Tag 是以一个 , 来分隔的,就像下面这一样。

所以我需要用 TextInput,并且 clean 直接不做任何处理直接返回,但是在 ArticleFormclean_tag_listsave 这两个方法里面处理 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment