主页分类操作

需求

个人主页的分类操作_第1张图片
如图,对文章进行归类后,在首页的左面会出现一个分类列表,以及么个分类对应的文章数目
modles.py中对应的数据库关系如下

class Article(models.Model):
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='文章标题',max_length=128)
    summary = models.CharField(verbose_name='文章简介',max_length=255)
    read_count = models.IntegerField(default=0)
    comment_count = models.IntegerField(default=0)
    up_count= models.IntegerField(default=0)
    down_count = models.IntegerField(default=0)
    create_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)

    blog=models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid',on_delete=models.CASCADE,)
    category = models.ForeignKey(verbose_name='所属分类',to='Category',to_field='nid',null=True,on_delete=models.CASCADE,)
    type_choices = [
        (1, "Python"),
        (2, "Linux"),
        (3, "OpenStack"),
        (4, "GoLang"),
    ]
    article_type_id = models.IntegerField(choices=type_choices, default=None)

    tags = models.ManyToManyField(
        to="Tag",
        through='Article2Tag',
        through_fields=('article', 'tag'),
    )

class Blog(models.Model):
    """
    博客信息
    """
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='个人博客标题',max_length=64)
    site = models.CharField(verbose_name='个人博客前缀',max_length=32,unique=True)
    theme = models.CharField(verbose_name='个人博客主题',max_length=32)
    user = models.OneToOneField(to='UserInfo',to_field='nid',on_delete=models.CASCADE,)
class Category(models.Model):
    """
    博主个人文章分类表
    """
    nid = models.AutoField(primary_key=True)
    title = models.CharField(verbose_name='分类标题',max_length=32)
    blog = models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid',on_delete=models.CASCADE,)

当用户输入了博客后缀后,通过后缀列出的,当前用户的分类信息

def home(request,site):
    blog = models.Blog.objects.filter(site=site).first()
    if not blog:
        return redirect('/')

    #当前博客的所有文章
    models.Article.objects.filter(blog=blog)#这里可以传入blog对象,也可以通过blog__id=blog.id的方式来过滤

    #当前所有博客的分类
    # cate_list = models.Category.objects.filter(blog=blog)
    # for item in cate_list:
    #     c = item.article_set.all().count()#通过反向查找每个类对应的所有文章的个数
    #     print(item,c)
    #但是上面的这个方法不好,他对数据库的操作比较多,我们可以使用下面的一次性查出来,通过一条来操作

    #下面的一条分类语法,
    # from django.db.models import Count
    # category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title').annotate(c=Count('nid'))
    # for title,conut in category_list:
    #     print(title,count)
    #

标签分类

class Tag(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(verbose_name='标签名称',max_length=32)
    blog = models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid',on_delete=models.CASCADE,)

class Article(models.Model):
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='文章标题',max_length=128)
    summary = models.CharField(verbose_name='文章简介',max_length=255)
    read_count = models.IntegerField(default=0)
    comment_count = models.IntegerField(default=0)
    up_count= models.IntegerField(default=0)
    down_count = models.IntegerField(default=0)
    create_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)

    blog=models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid',on_delete=models.CASCADE,)
    category = models.ForeignKey(verbose_name='所属分类',to='Category',to_field='nid',null=True,on_delete=models.CASCADE,)
    type_choices = [
        (1, "Python"),
        (2, "Linux"),
        (3, "OpenStack"),
        (4, "GoLang"),
    ]
    article_type_id = models.IntegerField(choices=type_choices, default=None)

    tags = models.ManyToManyField(
        to="Tag",
        through='Article2Tag',
        through_fields=('article', 'tag'),
    )

class Article2Tag(models.Model):
    article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid',on_delete=models.CASCADE,)
    tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid',on_delete=models.CASCADE,)

    class Meta:
        unique_together = [
            ('article', 'tag'),
        ]

views处理结果

#tag标签分类
    tag_list = models.Tag.objects.filter(blog=blog)
    for item in tag_list:
        c= item.article_set.all().count()
        print(item,c)
    ##上面的这种方法还是读取数据库次数多
    #方法一
    from django.db.models import Count
    models.Article.objects.filter(blog=blog).values('blog_id','tags__title').annotate(c=Count('nid'))
    #方法二
    ##通过manytomany来关联
    # models.Article2Tag.objects.values('article_id','tag_id','article__title','tag__title')#通过一张表就关联了三张表

    #方法三:有第三张表的前的情况
    models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))#这个是获取某个博客关联的文章id和tagid的关系
    #article_id     tag_id
    #   1           1
    #   1           2
    #   2           12

    ##方法四:如果没有第三张表,只是many2many自动生成的表,通过下面的方法就可以连表
    models.Article.objects.filter(blog=blog).values('nid','title','tags','tags__title').annotate(c=Count('nid'))#这里加了一个tags就把前2个表
    #联系到了一起,简历一个关系表

方法四,需要把tags里面的through去掉,把手动创建的第三张表去掉。然后来操作

时间分类

个人主页的分类操作_第2张图片
发现原生sql很好来写,但是django要怎么做?
个人主页的分类操作_第3张图片

%这个字符在python中格式字符串的时候,是不能保留的,如要要保留需要%%两个。专业就可以得到100%这样的,所以对于上面的年月,我们可以“%%Y-%%m”这样在python格式化完后,数据库之间就可以%Y这样了

sqlite的写法是这样个人主页的分类操作_第4张图片