Skip to content

Commit

Permalink
上传番外篇:外键那些事儿的代码和课件
Browse files Browse the repository at this point in the history
  • Loading branch information
HaddyYang committed Apr 3, 2019
1 parent abb5662 commit 80f37c0
Show file tree
Hide file tree
Showing 39 changed files with 626 additions and 0 deletions.
Empty file.
15 changes: 15 additions & 0 deletions 番外篇:外键那些事儿/content_type/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.contrib import admin
from .models import Article, Video, Comment

# Register your models here.
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'content']

@admin.register(Video)
class VideoAdmin(admin.ModelAdmin):
list_display = ['id', 'video_name', 'url']

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ['id', 'content_type', 'object_id', 'content_object', 'text']
5 changes: 5 additions & 0 deletions 番外篇:外键那些事儿/content_type/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ContentTypeConfig(AppConfig):
name = 'content_type'
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 2.1.7 on 2019-04-03 07:46

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('contenttypes', '0002_remove_content_type_name'),
]

operations = [
migrations.CreateModel(
name='Article',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=36)),
('content', models.TextField(blank=True)),
],
),
migrations.CreateModel(
name='Comment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('object_id', models.PositiveIntegerField()),
('text', models.TextField()),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
],
),
migrations.CreateModel(
name='Video',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('video_name', models.CharField(max_length=36)),
('url', models.URLField()),
],
),
]
Empty file.
78 changes: 78 additions & 0 deletions 番外篇:外键那些事儿/content_type/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType

# Create your models here.
# 文章表
class Article(models.Model):
title = models.CharField(max_length=36)
content = models.TextField(blank=True)
# comments = GenericRelation('Comment') # 由于Comment后面才定义,所以用字符串惰性引用

def __str__(self):
return '<Article: {0}>'.format(self.title)

__unicode__ = __str__

# 视频表
class Video(models.Model):
video_name = models.CharField(max_length=36)
url = models.URLField()

def __str__(self):
return '<Video: {0}>'.format(self.video_name)

__unicode__ = __str__

# 评论表
class Comment(models.Model):
# 无法同时指向多个对象
# article = models.ForeignKey(Article, on_delete=models.CASCADE)
# video = models.ForeignKey(Video, on_delete=models.CASCADE)

# 万能关系
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # 记录关联对象的类型
object_id = models.PositiveIntegerField() # 记录关联对象的主键值
content_object = GenericForeignKey('content_type', 'object_id') # 常规字段,便于使用

# 评论内容
text = models.TextField()

def __str__(self):
return '<Comment: {0}>'.format(self.text)

__unicode__ = __str__

# 正向,使用content_object可直接访问
'''
comment = Comment.objects.first()
obj = comment.content_object # 直接得到所被评论的对象
'''

# 反向,无法直接从其他对象找到Comment对应的评论
'''
from django.contrib.contenttypes.models import ContentType
article = Article.objects.first()
article_content_type = ContentType.objects.get_for_model(article)
# 通过Comment自身的筛选查询得到
comments = Comment.objects.filter(content_type=article_content_type, object_id=article.pk)
'''

# 反向,方法2,主动建立关系
# 参考:https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/#reverse-generic-relations
'''
from django.contrib.contenttypes.fields import GenericRelation
# 对应模型加入 comments = GenericRelation('Comment') 字段
article = Article.objects.first()
comments = article.comments.all()
'''


# content type 官方文档
# https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/

# 更多可以参考,我的Django2.0教程,第22课 评论功能设计和用户登录
# 链接:https://www.bilibili.com/video/av21029850
3 changes: 3 additions & 0 deletions 番外篇:外键那些事儿/content_type/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
3 changes: 3 additions & 0 deletions 番外篇:外键那些事儿/content_type/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.shortcuts import render

# Create your views here.
Binary file added 番外篇:外键那些事儿/db.sqlite3
Binary file not shown.
Empty file.
11 changes: 11 additions & 0 deletions 番外篇:外键那些事儿/foreign_key/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.contrib import admin
from .models import SchoolClass, Student

# Register your models here.
@admin.register(SchoolClass)
class SchoolClassAdmin(admin.ModelAdmin):
list_display = ['id', 'class_name', 'class_master']

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ['id', 'school_class', 'student_name', 'sex']
5 changes: 5 additions & 0 deletions 番外篇:外键那些事儿/foreign_key/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ForeignKeyConfig(AppConfig):
name = 'foreign_key'
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 2.1.7 on 2019-04-03 05:35

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='SchoolClass',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('class_name', models.CharField(max_length=12)),
('class_master', models.CharField(max_length=12)),
],
),
migrations.CreateModel(
name='Student',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('student_name', models.CharField(max_length=12)),
('sex', models.IntegerField(choices=[(0, '男'), (1, '女')], default=0)),
('school_class', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='foreign_key.SchoolClass')),
],
),
]
Empty file.
76 changes: 76 additions & 0 deletions 番外篇:外键那些事儿/foreign_key/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from django.db import models

# Create your models here.
# https://docs.djangoproject.com/en/2.2/ref/models/fields/#module-django.db.models.fields.related
# 班级表
class SchoolClass(models.Model):
class_name = models.CharField(max_length=12)
class_master = models.CharField(max_length=12)

def __str__(self):
return '<SchoolClass: {0}>'.format(self.class_name)

__unicode__ = __str__

# 学生表
class Student(models.Model):
school_class = models.ForeignKey(SchoolClass, on_delete=models.CASCADE)
# (on_delete属性说明)
# 必填,对应关联的记录(班级),删除的时候,该记录(学生)怎么处理
# 参考:https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.ForeignKey.on_delete

# 1、CASCADE, 级联删除。
# 当班级删除记录的时候,删除对应的所有学生。确保数据完整

# 2、PROTECT, 保护。
# 当班级删除记录的时候,若有学生关联该班级,则不给删除班级

# 3、SET_NULL, 设置为NULL。
# 当班级删除记录的时候,若有学生关联该班级,则将这些学生的班级外键字段,值设置为null。
# school_class = models.ForeignKey(SchoolClass, on_delete=models.SET_NULL, null=True) # 需要设置null为True

# 4、SET_DEFAULT,设置为默认值。
# def default_class():
# return SchoolClass.objects.first()
# school_class = models.ForeignKey(SchoolClass, on_delete=models.SET_DEFAULT, default=default_class) # 需要设置default

# 5、SET(),自定义方法,返回一个值,设置该字段的值
# 参考:https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.SET

# 6、DO_NOTHING,什么时候都不做。
# 这个会破坏数据完整性,慎用。


# (正向:顺理成章)
# s = Student.objects.first()
# s.school_class # 找到关联的班级对象

# (反向:冥冥之中)
# c = SchoolClass.objects.first()
# c.student_set.all() # xxxx_set 找到被关联的对象

# related_name,明确关系,班级通过什么属性找到学生
# school_class = models.ForeignKey(SchoolClass, on_delete=models.CASCADE, related_name='students')
# c = SchoolClass.objects.first()
# c.students.all()


# 编辑该字段,直接赋值即可
# c = SchoolClass.objects.first()
# s = Student()
# s.student_name = 'test'
# s.school_class = c
# s.save()


SEX_CHOICES = (
(0, '男'),
(1, '女'),
)
student_name = models.CharField(max_length=12)
sex = models.IntegerField(choices=SEX_CHOICES, default=0)

def __str__(self):
return '<Student: {0}>'.format(self.student_name)

__unicode__ = __str__
3 changes: 3 additions & 0 deletions 番外篇:外键那些事儿/foreign_key/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
3 changes: 3 additions & 0 deletions 番外篇:外键那些事儿/foreign_key/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.shortcuts import render

# Create your views here.
15 changes: 15 additions & 0 deletions 番外篇:外键那些事儿/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python
import os
import sys

if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'relationship.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
Empty file.
12 changes: 12 additions & 0 deletions 番外篇:外键那些事儿/many_to_many/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.contrib import admin
from .models import Author, Book

# Register your models here.
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
list_display = ['id', 'author_name']

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ['id', 'book_name']
filter_horizontal = ('authors',)
5 changes: 5 additions & 0 deletions 番外篇:外键那些事儿/many_to_many/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ManyToManyConfig(AppConfig):
name = 'many_to_many'
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 2.1.7 on 2019-04-03 06:11

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Author',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('author_name', models.CharField(max_length=24)),
],
),
migrations.CreateModel(
name='Book',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('book_name', models.CharField(max_length=48)),
('authors', models.ManyToManyField(to='many_to_many.Author')),
],
),
]
Empty file.
Loading

0 comments on commit 80f37c0

Please sign in to comment.