Python学习---Model拾遗[1]180318
Model: 强大的数据库操作,弱小的数据验证
Form: 强大的数据验证
ModelForm: 强大的数据验证 + 弱小的数据库操作
Model拾遗
Model基本操作
1. 创建数据库表
2. 修改表级别和行级别的数据
2.1 数据表操作
1.代码优先【Code First】: 创建类 --> 自动生成表 【Django】
2.数据库优先【DataBase First】: 创建表 --> 自动生成类 【Hibernate&Mybatit】
单 表:
一对一:
一对多:只能ForeignKey, 有约束关系
注:一对多在多的一方创建ForeignKey[从sql角度看清楚]
多对多:1. Django帮我们创建第三张表
models.ManyToManyField -->类中不添加任何字段,只是帮我们创建第三张表
2. 我们自己创建第三张表【推荐】
1. 创建一个类,定义2个外键,此时表关系一目了然
3. 我们自己创建第三张表,且让Django来引用
注:多对多只涉及正反查找问题,写在任意一个类即可
利用ManyToManyField创建第三张表的时候,DJangoAdmin里面添加内容是会有该字段内容
自定义的第三张表需要添加Favor类到admin里才能显示
2.2 数据行操作
使用Django帮我们创建第三张表效果:
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ ]
views.py
from django.shortcuts import render, redirect, HttpResponse from app01 import models
models.py
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1对多[无法用自定义,有约束关系] # 多对多[1. 自己创建第三张表 2. manytomany ] # 在DjangoAdmin里面如果自己创建第三张表,则DjangoAdmin里面不会有下拉框 # ManytoMany创建约束后,DjangoAdmin里面会有下拉框[因为DjangoAdmin使用的是ModelForm,它会将此作为一个字段显示] class UserType(models.Model): name = models.CharField(max_length=32) class News(models.Model): title = models.CharField(max_length=32) # Django帮我们创建第三张表favor favor = models.ManyToManyField("User") # DjangoAdmin里面显示2个字段[title + favor多选框] # 自定义的第三张表,该示例中引用的是many2many创建第三张表【admin中未注册该类】 class Favor(models.Model): new = models.ForeignKey("News", on_delete=True, related_name='u') user = models.ForeignKey("User", on_delete=True, related_name='n')
app01/admin.py
from django.contrib import admin # Register your models here. from app01 import models admin.site.register(models.User) admin.site.register(models.News) admin.site.register(models.UserType)
页面显示;
初始化数据库和admin用户
python manage.py makemigrations python manage.py migrate python manage.py createsuperuser
使用自定义的第三张表Favor的效果:
models.py
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1对多[无法用自定义,有约束关系] # 多对多[1. 自己创建第三张表 2. manytomany ] # 在DjangoAdmin里面如果自己创建第三张表,则DjangoAdmin里面不会有下拉框 # ManytoMany创建约束后,DjangoAdmin里面会有下拉框[因为DjangoAdmin使用的是ModelForm,它会将此作为一个字段显示] class UserType(models.Model): name = models.CharField(max_length=32) class News(models.Model): title = models.CharField(max_length=32) # Django帮我们创建第三张表favor【这里不引用它】 # favor = models.ManyToManyField("User") # 自定义的第三张表,【admin中注册该类,引用自定义表】 class Favor(models.Model): new = models.ForeignKey("News", on_delete=True, related_name='u') user = models.ForeignKey("User", on_delete=True, related_name='n')
app01/admin.py
from django.contrib import admin # Register your models here. from app01 import models admin.site.register(models.User) admin.site.register(models.News) admin.site.register(models.UserType) admin.site.register(models.Favor)
页面显示:
使用many2many + 自定义的第三张表:
更改了表单,需要重新写入数据库
注意:
1.因为我们使用的through_field()对Favor的部分字段进行关联,并未关联全部,所以页面是无法直接添加数据的。
2.我们使用through对自定义的Favor和News进行关联后,是不能直接使用add(),remove()的操作方法的,
但是可以利用all(),filter()进行查找操作。同时obj.favor.clear()也是可以用的...
models.py
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True)# 1对多[无法用自定义,有约束关系] # 多对多[1. 自己创建第三张表 2. manytomany ] # 在DjangoAdmin里面如果自己创建第三张表,则DjangoAdmin里面不会有下拉框 # ManytoMany创建约束后,DjangoAdmin里面会有下拉框[因为DjangoAdmin使用的是ModelForm,它会将此作为一个字段显示] class UserType(models.Model): name = models.CharField(max_length=32) class News(models.Model): title = models.CharField(max_length=32) # Django帮我们创建第三张表且指向我们自定义的Favor表并添加指定的字段 favor = models.ManyToManyField("User", through='Favor', through_fields=('new_obj', 'user_obj')) # 自定义的第三张表,【admin中注册该类,引用自定义表】 class Favor(models.Model): new1 = models.ForeignKey("News", on_delete=True, related_name='u1') # 不引用该字段 New_obj = models.ForeignKey("News", on_delete=True, related_name='u') user_obj = models.ForeignKey("User", on_delete=True, related_name='n')
app01/admin.py
from django.contrib import admin # Register your models here. from app01 import models admin.site.register(models.User) admin.site.register(models.News) admin.site.register(models.UserType) admin.site.register(models.Favor)
页面显示:
初始化数据库
python manage.py makemigrations python manage.py migrate
问题解决:
问题现象:
问题定位:
Django帮创建了多对多的News.Favor和我们自定义的class Favor,此时2个是一个功能,所以系统提示我们查询的时候名称冲突了,添加一个查询别名即可解决。
一对一操作:表和表的关联
2种方法:
userProfile = models.ForeignKey("UserProfile", on_delete=True, unique=True) # 唯一索引
userDetail = models.OneToOneField("UserProfile", on_delete=True) # 一对一的另一种写法
注:如果我们遇到了一个有很多列的表单时,可以拆分关键独立一个表单,然后利用表和表之间一对一的关系进行关联,可以减少sql查询时候的时间
Models.py
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) userType = models.ForeignKey("UserType", on_delete=True) # 1对多[无法用自定义,有约束关系] userProfile = models.ForeignKey("UserProfile", on_delete=True, unique=True) # 一对一,唯一索引 userDetail = models.OneToOneField("UserProfile", on_delete=True) # 一对一的另一种写法 # Sql优化: 长度固定的字段放在最前面 class UserProfile(models.Model): pwd = models.CharField(max_length=32)
更多参考:
Model操作;:http://www.cnblogs.com/wupeiqi/articles/6216618.html
Form操作; :http://www.cnblogs.com/wupeiqi/articles/6144178.html
Model操作;:http://www.cnblogs.com/wupeiqi/articles/6229414.html
-------------------------------------------
个性签名: 所有的事情到最後都是好的,如果不好,那說明事情還沒有到最後~
本文版权归作者【小a玖拾柒】和【博客园】共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利!