一、中介模型:多对多添加的时候用到中介模型

自己创建的第三张表就属于是中介模型
class Article(models.Model):
    '''
    文章表
    '''
    title = models.CharField(max_length=64,verbose_name="文章标题")
    summary = models.CharField(max_length=244, verbose_name="文章概要")
    create_time = models.DateTimeField(verbose_name="创建时间",auto_now_add=True)
    update_time = models.DateTimeField(verbose_name="修改时间",auto_now=True)
    up_count = models.IntegerField(verbose_name="点赞数",default=0)
    down_count = models.IntegerField(verbose_name="点灭数",default=0)
    comment_count = models.IntegerField(verbose_name="评论数",default=0)
    read_count = models.IntegerField(verbose_name="阅读数",default=0)

    user = models.ForeignKey(to="UserInfo",verbose_name="所属作者",null=True,blank=True)
    classify = models.ForeignKey(to="Classfication",verbose_name="所属类别",null=True,blank=True)
    tags = models.ManyToManyField(to="Tag",through="Article2tag",through_fields=('article', 'tag'),verbose_name="所属标签")
    site_article_category = models.ForeignKey(to="SiteArticleCategory",verbose_name="所属文章分类",null=True,blank=True)
    class Meta:
        verbose_name_plural = "文章表"
    def __str__(self):
        return self.title




class Tag(models.Model):
    '''标签表'''
    name = models.CharField(max_length=32,verbose_name="标签名")
    blog = models.ForeignKey(to="Blog",verbose_name="所属博客")
    class Meta:
        verbose_name_plural = "标签表"

    def __str__(self):
        return self.name


class Article2tag(models.Model):
    article = models.ForeignKey(verbose_name="文章",to="Article")
    tag = models.ForeignKey(verbose_name="标签",to="Tag")
    class Meta:
        verbose_name="文章和标签关系表"
        '''联合唯一'''
        unique_together = [
            ("article","tag")
        ]
    def __str__(self):
        return self.article.title + "  "+self.tag.name

像是这样自己创建的第三张表就属于是中介模型。一般就Django会给我们自动创建第三张表,
人家自己创建的只是有关系字段,不能在增加其他的字段了,
如果根据需求添加其他字段,不需要ManytoMany自己创建第三张表就自己设置第三张表
这就需要我们自己去创建第三张表。
当然我现在设计的
Article2tag这个第三张表就可以在里面添加其他你需要的字段。

 

如果用了中介模型了,就不能在用add,remove了

此时,唯一的办法就是创建中介模型的实例。

clear() 方法却是可用的。它可以清空某个实例所有的多对多关系:

cate = request.POST.get("cate")
tag = request.POST.getlist("tag")
article_obj = models.Article.objects.create(title=title,summary=content[0:30],create_time=datetime.datetime.now(),user=request.user,classify_id = cate)
models.Article_detail.objects.create(content=content,article=article_obj)
if tag:
  for i in tag:   #[2,4]
      models.Article2tag.objects.create(tag_id=i,article_id=article_obj.id)   #直接从关系表里面去查

 

remove()方法被禁用也是出于同样的原因。clear() 方法却是可用的。它可以清空某个实例所有的多对多关系:

二、优化查询

简单使用

对于一对一字段(OneToOneField)和外键字段(ForeignKey),可以使用select_related 来对QuerySet进行优化。

它会生成一个复杂的查询并引起性能的损耗,但是在以后使用外键关系时将不需要数据库查询。

简单说,在对QuerySet使用select_related()函数后,Django会获取相应外键对应的对象,从而在之后需要的时候不必再查询数据库了。

select_related() 查询的区别。

下面是一个标准的查询:


obj = models.Article.objects.get(id=2)
print(obj.classify.title) #走两次数据库,基于对象的属于子查询,基于双下划线的属于连表查询

sql是这样的

 1 '''
 2  
 3 SELECT
 4     "blog_article"."nid",
 5     "blog_article"."title",
 6     "blog_article"."desc",
 7     "blog_article"."read_count",
 8     "blog_article"."comment_count",
 9     "blog_article"."up_count",
10     "blog_article"."down_count",
11     "blog_article"."category_id",
12     "blog_article"."create_time",
13      "blog_article"."blog_id",
14      "blog_article"."article_type_id"
15              FROM "blog_article"
16              WHERE "blog_article"."nid" = 2; args=(2,)
17  
18 SELECT
19      "blog_category"."nid",
20      "blog_category"."title",
21      "blog_category"."blog_id"
22               FROM "blog_category"
23               WHERE "blog_category"."nid" = 4; args=(4,)
24  
25  
26 '''
View Code

相关文章:

  • 2021-05-23
  • 2021-11-04
  • 2021-05-25
猜你喜欢
  • 2021-11-19
  • 2021-11-28
  • 2021-12-15
  • 2021-09-16
  • 2021-11-09
  • 2021-12-14
  • 2022-12-23
相关资源
相似解决方案