zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    linux环境下时区无法设置(UTC无法更改为CST)的问题解决
    SUSE12 网卡配置、SSH远程配置、解决CRT密钥交换失败,没有兼容的加密程序
    SUSE12 操作系统安装
    Unity技术支持团队性能优化经验分享
    基于unity3d游戏的android版本逆向初探
    Unity手游引擎安全解析及实践
    盛大游戏技术总监徐峥:Unity引擎使用的三种方式
    基于Unity 5的次世代卡通渲染技术 -- Unite 2017 米哈游总监贺甲分享实录
    欢乐互娱庞池海:《龙之谷》项目性能优化经验分享
    ue4 htcvivi简单配置
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9417429.html
Copyright © 2011-2022 走看看