Python学习---Model拾遗[1]180318

Model: 强大的数据库操作,弱小的数据验证

Form:  强大的数据验证

ModelForm: 强大的数据验证 + 弱小的数据库操作

Model拾遗

image

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)

页面显示;

image

初始化数据库和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)

页面显示:

image

使用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)

页面显示:

image

初始化数据库

python manage.py makemigrations
python manage.py migrate

问题解决:

问题现象:

image

问题定位:

    Django帮创建了多对多的News.Favor和我们自定义的class Favor,此时2个是一个功能,所以系统提示我们查询的时候名称冲突了,添加一个查询别名即可解决。

image

一对一操作:表和表的关联

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

原文地址:https://www.cnblogs.com/ftl1012/p/9417429.html