django geneticForeignkey相关
来源:互联网 发布:excel数据透视筛选器 编辑:程序博客网 时间:2024/06/06 05:54
In some cases the we might want to store generic model object, rather a particular specific model as 'ForeignKey'. Here is scenario of such kind. Suppose there are models like User, Project, Ticket and TimeLine as below.
class Ticket(models.Model): name = models.CharField(max_length=200, verbose_name=_("name")) slug = models.SlugField(max_length=250, null=False, blank=True, verbose_name=_("slug"))class Project(models.Model): name = models.CharField(max_length=200, verbose_name=_("name")) slug = models.SlugField(max_length=250, null=False, blank=True, verbose_name=_("slug"))class User(models.Model): name = models.CharField(max_length=200, verbose_name=_("name")) slug = models.SlugField(max_length=250, null=False, blank=True, verbose_name=_("slug"))class Timeline(models.Model): involved_object = ***** event_type = models.CharField(max_length=250, default="created")
If we want to store the user activities with these models like "created User, created Project, created Task" in time line, we have to create all the three models( User, Project, Task)as ' ForeignKey' fields. This is not a good programming practice. To overcome this, Django's contenttypes framework provides a special field type (GenericForeignKey) which allows the relationship to be with any model.
Using 'GenericForeignKey' :
Here is the solution for the above scenario. There are three parts to setting up a GenericForeignKey:
- Give your model a ForeignKeyto ContentType. The usual name for this field is “content_type”.
- Give your model a field that can store primary key values from the models you’ll be relating to. For most models, this means aPositiveIntegerField. The usual name for this field is “object_id”.
- Give your model a GenericForeignKey, and pass it the names of the two fields described above. If these fields are named “content_type” and “object_id”, you can omit this – those are the default field names GenericForeignKey will look for.
So by following the above three steps the TimeLine will look as following.
class Timeline(models.Model): content_type = models.ForeignKey(ContentType, related_name="content_type_timelines") object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') event_type = models.CharField(max_length=250, default="created")
For example if we want to store the event "created Project" after the project is created, the following snippet will do things for us.
t1 = TimeLine(content_object=project_object)t1.save()
But due to the way 'GenericForeignKey' is implemented, you cannot use such fields directly with filters (filter() and exclude(), for example) via the database API. Because a GenericForeignKey isn’t a normal field object, the following examples will not work:
TimeLine.objects.filter(content_object=project_object)# This will also failTimeLine.objects.get(content_object=project_object)
To retrieve the TimeLine object with the project object, we have to follow these steps.
- Get the 'ContentType' object with the follwoing code.
from django.contrib.contenttypes.models import ContentType contenttype_obj = ContentType.objects.get_for_model(project_object)
- "object_id" is stored with project_object.id
TimeLine.objects.filter(object_id=project_object.id, content_type=contenttype_obj)
- django geneticForeignkey相关
- Django相关
- Django相关
- django相关
- django分页相关类
- Django相关函数
- django相关资源
- django数据库相关操作
- django html相关过滤器
- Django数据库查询相关
- django相关文档说明
- Django 视图相关
- Django-admin使用相关
- django相关资源
- django数据库错误相关问题
- Django——Url相关
- Python Django App开发相关
- Django-restful-framwork(serializer相关)
- 关于Angular实践的小小总结
- React.js学习笔记
- C语言基本数据类型简介
- 常用js校验
- 股票入门基础知识39:图表分析中添加趋势线
- django geneticForeignkey相关
- 三:C++对C的扩展(感谢传智播客)
- Android中的Handler的post方法详解
- 【图论】【二叉树】以括号形式输出二叉树
- 猴子吃桃的相关问题
- LeetCode——3. Longest Substring Without Repeating Characters
- maven 阿里云 国内镜像 中央仓库 亲测可用
- 浅谈MyBatis 之 入门(一)
- pat-bl-1027