django常用组件学习2——django-taggit

标签:django

标签(tag)是比较新兴的一种信息管理方式,与经典的分类的区别在于:

  • 同一篇文章标签(Tag)可以用多个,但通常只能属于一个分类;
  • 标签(Tag)一般是在写作完成后,根据文章大意进行添加的;
  • 标签(Tag)可以把文章中重点词语提炼出来,有关键词的意义,但是分类没有;
  • 标签(Tag)通常反映了您的主要关注点,比如财经、互联网、体育等等;
  • 标签(Tag)给了我们一条联系他人的纽带,通过标签(Tag)可以找到您的“同好”。

现在很多网站,论坛,博客和软件都是支持标签(TAG)的那么我们怎么用django实现标签(TAG)功能呢,今天我就来学习一下django-taggit组件。

组件的github主页为https://github.com/alex/django-taggit

基本使用方式:

我们按官方文档来练习. 安装

$ pip install django-taggit

一般不会有什么问题。 第二步,在项目中使用,我想在前面我学习django-filter的项目里,按照文档“Add “taggit” to your project’s INSTALLED_APPS setting.” 结果项目启动时报错。

taggit.taggeditem: 'content_type' has a relation with model <class 'django.contrib.contenttypes.models.ContentType'>, which has either not been installed or is abstract.

这里因为还需要把“django.contrib.contenttypes”加入到 “INSTALLED_APPS” 中。 然后运行manage.py syncdb 会生成表【TAGGIT_TAG】和【TAGGIT_TAGGEDITEM】。我们可以查看一下这两个表的结构:

PS .\manage.py dbshell
SQLite version 3.8.7.2 2014-11-18 20:57:56
Enter ".help" for usage hints.
sqlite> .schema taggit_tag
CREATE TABLE "taggit_tag" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(100) NOT NULL UNIQUE,
    "slug" varchar(100) NOT NULL UNIQUE
);
sqlite> .schema taggit_taggeditem
CREATE TABLE "taggit_taggeditem" (
    "id" integer NOT NULL PRIMARY KEY,
    "tag_id" integer NOT NULL REFERENCES "taggit_tag" ("id"),
    "object_id" integer NOT NULL,
    "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id")
);
CREATE INDEX "taggit_taggeditem_5659cca2" ON "taggit_taggeditem" ("tag_id");
CREATE INDEX "taggit_taggeditem_846f0221" ON "taggit_taggeditem" ("object_id");
CREATE INDEX "taggit_taggeditem_37ef4eb4" ON "taggit_taggeditem" ("content_type_id");

下面我们来修改模型:

from taggit.managers import TaggableManager
class Cars(models.Model):
    # ... 原有字段略
    tags = TaggableManager()
    class Meta:
        db_table = 'office_cars'    

在命令行测试一下:

.\manage.py shell
In [1]: from apps.office.cars.models import Cars
In [2]: car = Cars()
In [3]: car.car=u'测试车1'
In [4]: car.save()
In [5]: car.tags.add(u'宝马',u'跑车')
In [6]: car2 = Cars()
In [7]: car2.car=u'测试车2'
In [8]: car2.save()
In [9]: car2.tags.add(u'摩托','跑车')
In [10]: car2.tags.all()
Out[10]: [<Tag: 摩托>, <Tag: 跑车]
In [11]: Cars.objects.filter(tags__name__in=[u"跑车"])
Out[12]: [<Cars: 测试车1>,<Cars: 测试车2>]

结合ModelForm使用:

使用forms接回request参数时会把输入的标签参数进行智能的分隔处理,分隔规则如下表。

Tag input string Resulting tags Notes
apple ball cat ["apple", "ball", "cat"] No commas, so space delimited
apple, ball cat ["apple", "ball cat"] Comma present, so comma delimited
“apple, ball” cat dog ["apple, ball", "cat", "dog"] All commas are quoted, so space delimited
“apple, ball”, cat dog ["apple, ball", "cat dog"] Contains an unquoted comma, so comma delimited
apple “ball cat” dog ["apple", "ball cat", "dog"] No commas, so space delimited
“apple” “ball dog ["apple", "ball", "dog"] Unclosed double quote is ignored

注意:当“commit=False”时,需要用“save_m2m()”方法保存多对多关系数据,如下:

if request.method == "POST":
    form = MyFormClass(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        # Without this next line the tags won't be saved.
        form.save_m2m()

其他:

Written on 2015-06-10
上篇: django常用组件学习1——django-filter
下篇: 使用jquery.qrcode生成二维码