zoukankan      html  css  js  c++  java
  • Django ContentTypes框架使用场景

    Django contenttypes是一个非常有用的框架,主要用来创建模型间的通用关系(generic relation)。不过由于其非常抽象,

    理解起来并不容易。当你创建一个django项目的时候,可以看到在默认的INSTALL_APPS已经包含了django.contrib.contenttypes。

    今天我们来重点讲下它的使用场景及如何使用django contenttypes。

    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
    ]

    Django ContentTypes框架使用场景

    假设我们创建了如下模型,里面包含文章Post,Picture和评论Comment模型。

    Comment可以是对Post的评论,也可以是对Picture的评论。

    如果你还想对其它对象(比如回答,用户) 进行评论, 这样你将需要在comment对象里添加非常多的ForeignKey。

    你的直觉会告诉你,这样做很傻,会造成代码重复和字段浪费。一个更好的方式是,只有当你需要对某个对象或模型进行评论时,

    才创建comment与那个模型的关系。这时你就需要使用django contenttypes了。

    from django.db import models
    from django.contrib.auth.models import User
     
    # Create your models here.
     
     
    class Post(models.Model):
        author = models.ForeignKey(User)
        title = models.CharField(max_length=75)
        body = models.TextField(blank=True)
     
     
    class Picture(models.Model):
        author = models.ForeignKey(User)
        image = models.ImageField()
        caption = models.TextField(blank=True)
     
     
    class Comment(models.Model):
        author = models.ForeignKey(User)
        body = models.TextField(blank=True)
        post = models.ForeignKey(Post, null=True)
        picture = models.ForeignKey(Picture, null=True)
    

    Django ContentType提供了一种GenericForeignKey的类型,通过这种类型可以指定content_object。修改过的comment模型如下图所示:

     import ContentType
     import GenericForeignKey
    
    class Comment(models.Model):
        author = models.ForeignKey(User)
        body = models.TextField(blank=True)

    content_type
    = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField() content_object = GenericForeignKey(content_type,object_id)

    comment里加了3个字段:

    • content_type: 内容类型,代表了模型的名字(比如Post, Picture)

    • object_id: 传入对象的id

    • content_object: 传入的实例化对象,其包含两个属性content_type和object_id。

    当你需要对某篇文章或某个图片进行评论时(建立评论关系),

    你只需要将实例化的对象user, post或picture传入comment。

    这样实现了按需建立评论关系。首先你先需要实例化对象。

    user = User.objects.create_user(username='user1', password='2333')
    post = Post.objects.create(author=user,
                               title='title1',
                               body='')
    picture = Picture.objects.create(author=user,
                                     image="default.png",
                                     caption='picture1')

    然后在views或者shell里,你可以按如下代码建立评论关系。

     
     from foreign.models import Post, Picture, Common
    >>> from django.contrib.auth.models import User
    >>> user = User.objects.get(username='user1') >>> post = Post.objects.get(title='title1')
    >>> c = Comment.objects.create(author=user, body='', content_object=post) >>> picture = Picture.objects.get(caption='picuture1') >>> c1 = Comment.objects.create(author=user, body='', content_object=picture)

    然而上述创建评论的方式我们并不推荐

    我们更希望直接从模型中获取或创建comment,

    我们只需在模型中创建一个与Comment的GenericRelation即可。

    注意该字段不会存储于数据库中。

    from django.contrib.contenttypes.fields import GenericRelation
    
    class Post(models.Model):
      author = models.ForeignKey(User)
      title = models.CharField(max_length=75)
      body = models.TextField(blank=True)
      comments = GenericRelation('Comment')
    
    class Picture(models.Model):
      author = models.ForeignKey(User)
      image = models.ImageField()
      caption = models.TextField(blank=True)
      comments = GenericRelation('Comment')
    
    >>> me = User.objects.get(username='myusername')
    >>> pic = Picture.objects.get(author=me)
    >>> pic.comments.create(author=me, body="Man, I'm cool!")
    >>> pic.comments.all()[<Comment: "Man, I'm cool!">]
    

    值得注意的是,如果在Post中定义了GenericRelation,删除了一个post实例,

    在Comment中所有与post相关实例也会被删除。GenericForeignKey不支持设置on_delete参数。 

    因此,如果对级联删除不满意的话就不要设置GenericRelation。

  • 相关阅读:
    Android动态加载jar/dex
    aiXcoder安装&使用
    笨办法学python 13题:pycharm 运行
    python2.7安装numpy、pandas、matplotlib库
    win10在文件夹下打开powershell
    SpringCloud:(一)服务注册与发现
    pycharm2018.2安装
    Python2.7安装&配置环境变量
    centos7配置NTP时间服务器
    centos7:Zookeeper集群安装
  • 原文地址:https://www.cnblogs.com/Rivend/p/12048936.html
Copyright © 2011-2022 走看看