Django-orm连接mysql

Django-orm连接mysql

  • MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
  • ORM是“对象-关系-映射”的简称,主要任务是:
    • 根据对象的类型生成表结构
    • 将对象、列表的操作,转换为sql语句
    • 将sql查询到的结果转换为对象、列表
  • 这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
  • Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表
    Django-orm连接mysql_第1张图片

1.环境配置

1.1mysqlclient安装

pip install mysqlcilent
pip install -i https://pypi.douban.com/simple mysqlclient
阿里云 http://mirrors.aliyun.com/pypi/simple/ 
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 
豆瓣(douban) http://pypi.douban.com/simple/ 
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 
#第一行命令不行尝试第二行,再不行就换源尝试,我是用阿里的直接成功了

如果是windonws环境可能不能直接安装,需要进行以下步骤:

  • 下载mysqlcilent安装包:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
  • 进入mysqliclient路径:输入 pip Install mysqliclient

如果实在不行,这边建议您百度或者降低django版本。

1.2setting配置

DATABASES = {
	    'default': {
	        'ENGINE': 'django.db.backends.mysql',
	        'NAME': 'student',
	        'USER': 'root',
	        'PASSWORD': 'root',
	        'HOST': '127.0.0.1',
	        'PORT': '3306',
	    }
	}
# 在应用创建之后记得加入install_app项

2.创建表

下面的介绍以我写的一个用户注册登录程序为例

在model.py文件内创建一个继承了 modles.Model的类,这就会在数据库内创建一个对应的表,注意表的名称为models.py所在的问价夹名_你创建的类名

# models.py
from django.db import models

class models_db1(models.Model):
    UserName = models.CharField(max_length=11)
    PassWord = models.CharField(max_length=11)

在这里我的app名为models_lr,所以在数据库查到的对应的表名为models_lr_models_db1

3.注册

写完类之后需要注意在对应的admin.py里进行注册

admin.py

from django.contrib import admin

from models_lr.models import models_db1

admin.site.register(models_db1)

4.生成迁移文件并迁移

#在terminal 终端输入
python manage.py makemigrations #生成迁移文件,在对应文件夹的migrations问价夹里可以找到
#再输入
python manege.py migrate #数据迁移

5.views视图函数里对数据库进行操作

from django.shortcuts import render, redirect

from models_lr import models


def get_un(UN):  #从数据库中获取数据
    s = models.models_db1.objects.filter(UserName=UN).values()
    for i in s:
        i = str(i)
        return str(i.split(' ')[3][1])
#不知道为什么我获取到的是一个对象 所以要在后面加values()来取值

def updata_db(u, p):  #因为不会写加入的英语。这其实是一个增加数据的操作
    updata = models.models_db1()
    updata.UserName = u
    updata.PassWord = p
    updata.save()

def cheak_cookie(fun): #检测cooike值来做一个持续登录
    def wa(request):
        if request.COOKIES.get('COOKIE')!=None:
            return fun(request)
        else:
            return render(request,'login.html',context={'a':'cookie已失效,请重新登录'})
    return wa
def register(request):  #用户注册
    if request.method == 'GET':
        return render(request, 'register.html')
    if request.method == 'POST':
        UserName = request.POST.get('UserName')
        PassWord = request.POST.get('PassWord')
        PassWord_1 = request.POST.get('PassWord_1')
        if UserName != '' and PassWord != '' and PassWord_1 != '':
            if not models.models_db1.objects.filter(UserName=UserName).exists():
                if PassWord == PassWord_1:
                    updata_db(UserName, PassWord)
                    str = '/models/index/?username=' + UserName
                    response = redirect(str)
                    response.set_cookie(key=UserName, value=PassWord, max_age=3600)
                    return response
                else:
                    return render(request, 'register.html', context={'a': '密码不一致'})
            else:
                return render(request, 'register.html', context={'a': '用户名已存在'})
        else:
            return render(request, 'register.html', context={'a': '输入有空'})


def login(request): #用户登录
    if request.method == 'GET':
        return render(request, 'login.html')
    if request.method == 'POST':
        UserName = request.POST.get("UserName")
        PassWord = request.POST.get("PassWord")
        if UserName != '' and PassWord != '':
            if get_un(UserName) != PassWord:
                return render(request, 'login.html', context={'a': '账号或密码错误'})
            else:
                str1 = "/models/index/?username=" + UserName
                response = redirect(str1)
                response.set_cookie(key=UserName, value=PassWord, max_age=300)
                return response
        else:
            return render(request, 'login.html', context={'a': '输入有空'})

@cheak_cookie
def index(request):  #主界面
    username = request.GET.get("username")
    dit={'a':username}
    response = render(request, "index.html",context=dit)
    return response

6.对应的其它页面

#项目的url
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('models/',include('models_lr.urls')),
]
#models_db的url
from django.conf.urls import url

from models_lr import views

urlpatterns=[
    url(r'^register/$',views.register),
    url(r'^login/$',views.login),
    url(r'^index/$',views.index),
]
#html文件太多下面只给出一个
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
<div align="center">
    <h1>{{ a }}</h1>  #用来显示报错信息
    <form action="/models/register/"   method="POST">
        {% csrf_token %}
         用户名:  <input type="text" name="UserName"> <br>
          密码:    <input type="text" name="PassWord"><br>
        确认密码:<input type="text" name="PassWord_1"><br>
        <input type="submit" value="注册">
    </form>
</div>
</body>
</html>

7.orm的字段

AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -3276832767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 032767
    IntegerField(Field)
        - 整数列(有符号的) -21474836482147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 02147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -92233720368547758089223372036854775807

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField)- 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型

8.orm常用参数

 1、 null=True
	   数据库中字段是否可以为空
	2、 blank=True
	   django的 Admin 中添加数据时是否可允许空值
	    #一般null=True & blank=True 咱们搭配着用,出现null=True就用上blank=True
	3、 primary_key = True
	   主键,对AutoField设置主键后,就会代替原来的自增 id4、 auto_now 和 auto_now_add
	   auto_now   自动创建---无论添加或修改,都是当前操作的时间
	   auto_now_add  自动创建---永远是创建时的时间
    ## 二者选一 
	5、 choices  (后台admin下拉菜单)
	     USER_TYPE_LIST = (
	         (1,u'超级用户'),
	         (2,u'普通用户'),
	     )
	     user_type = 					models.IntegerField(choices=USER_TYPE_LIST,default=1,verbose_name=u'用户类型')
	6、 max_length 最大长度
	7、 default  默认值
	8、 verbose_name  Admin(后台显示的名称)中字段的显示名称
	9、 name|db_column  数据库中的字段名称
	10、unique=True  不允许重复
	11、db_index = True  数据库索引,例如:如果你想通过name查询的更快的话,给他设置为索引即可
	12、editable=True  在Admin里是否可编辑
	13、error_messages=None  错误提示
	14、help_text  在Admin中提示帮助信息
	15、validators=[] 自定义验证器
	16、upload-to      指定上传路径

9.单表的操作

1.查询数据:
方式1:get-------Obj 得到具体对象
obj=models.Publisher.objects.get(id=1)
方式2:filter---->Queryset
obj=models.Publisher.objects.filter(id=1).first()
2.添加数据:
方式1:create
    obj=Book.objects.create()
方式2:save
    obj=Book(title="A")
    obj.save()
    或者:obj=Book()
    book.title="A"
    book.save()
3.修改数据:
    queryset=models.Publisher.object.filter(id=1)
    obj=models.Publisher.object.get(id=1)
    方式1:update------->调用的对象必须是queryset
    queryset.update(price=100)
    或者:queryset.update(**{"price":100})
    方式2:Obj---->使用对象
    obj.name=new_name
    obj.save()
4.删除数据:delete
queryset和obj均可使用
    queryset.delete()
    model_obj.delete()
models.Publisher.objects.get(id=1).delete()
## 10.查询方式汇总
返回QuerySet的有:
    1. all()
    3. filter()
    4. exclude()
    7. values_list()  --> 元祖
    8. values()       --> 字典
    9. order_by()
    10. reverse()
    13. distinct()
返回对象:  
    2. get()
    5. first()
    6. last()
返回数字:
    11. count()
返回布尔值:
    12. exist()  
<1> all():                 查询所有结果
<2> filter(**kwargs):      得到结果集 是个列表<QuerySet [<Publisher: Publisher object>]>
ret = models.Person.objects.filter(id=100) 不存在返回一个空的QuerySet,不会报错
就算查询的结果只有一个,返回的也是QuerySet,我们要用索引的方式取出第一个元素
ret = models.Person.objects.filter(id=1)[0]
<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
<4> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象
<5> values(*field):        返回一个可迭代的字典序列
ret = models.Person.objects.values("name", "birthday") 返回一个QuerySet对象,里面都是字典。 不写字段名,默认查询所有字段
<6> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
ret = models.Person.objects.values_list()
<7> order_by(*field):      对查询结果排序
ret = models.Person.objects.all().order_by("birthday")
<8> reverse():             对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
 对有序的QuerySet才能调用reverse ret = models.Person.objects.all().count()
<9> distinct():            从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
<11> first():              返回第一条记录
<12> last():               返回最后一条记录
<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

你可能感兴趣的:(Python-Django)