1. 程式人生 > 其它 >三秒鐘解決MySQL 8.0 Command Line Client開啟時閃退的問--小白來搞笑的

三秒鐘解決MySQL 8.0 Command Line Client開啟時閃退的問--小白來搞笑的

Django ORM

目錄
orm不會建立庫,只能建立到表的層面。需要自己手動敲命令建立庫

1、建立模型表

ORM:"""物件關係對映"""
作用:能夠讓一個不會用sql語句的小白,也能通過python面向物件的程式碼簡單快捷的操作資料庫
不足之處:封裝成都太高,有時候sql效率偏低,需要自己寫sql語句


類				     表
	
物件					記錄

物件屬性			記錄某個欄位對應的值
  1. 第一步:先去應用下的models.py中書寫一個模型類
# 應用下的models.py

class User(models.Model):
    # id int primary key auto_increment
    id = models.AutoField(parmary_key=True)
    # username varchar(32)
    username = models.CharField(max_length=32)
    # passwrod int
    password = models.IntegerField()
   

************************************2.資料庫遷移命令**************************************************
 python manage.py makemigrations  將操作記錄記錄到小本本上(migrations資料夾)
 python manage.py migrate   將操作真正同步到資料庫中
********************************************************************************************************

#應用下的modles.py
from django.db import models


# Create your models here.

class User(models.Model):
    # id int primary key auto_increment
    id = models.AutoField(primary_key=True,verbose_name='主鍵')
    # username varchar(32)
    username = models.CharField(max_length=32, verbose_name='使用者名稱')

    """
    CharField必須指定max_length引數,不指定會直接報錯
    verhose_name該引數是所有欄位都有的,就是用來對欄位的解釋
    """
    # passwrod int
    password = models.IntegerField(verbose_name='密碼')


class Author(models.Model):
    # 由於一張表中必須要有一個主鍵欄位,並且一般情況下都叫id欄位
    # 所以orm當不定義主鍵欄位的時候,orm會自動建立一個名為id欄位
    # 也就意味著後續再建立模型表的時候,如果主鍵欄位名沒有額外的叫法,那麼主鍵欄位可以省略不寫

    username = models.CharField(max_length=32)
    password = models.IntegerField()
  1. 第二步:資料庫遷移命令
 python manage.py makemigrations   #⽣成資料庫遷移⽂件

應用資料夾下的migrations資料夾下多了一個0001._initial.py日誌檔案

 python manage.py migrate  #⽣成資料庫表 
#將操作真正同步到資料庫中

資料庫遷移的兩條命令輸入完成後,此時資料庫中會出現很多張表

一個Djanog專案可以有多個應用,那麼多個應用之間可能會出現表名衝突的情況,那麼加上字首就可以完全避免衝突

"""
只要修改了models.py中跟資料庫相關的程式碼,就必須重新執行資料遷移的兩條命令
"""

2、欄位的增刪改查

2. 1、 欄位的增加
"""
1.可以在終端內直接給出預設值
	age=models.IntegerField(verbose_name='年齡')
2.該欄位可以為空
	 info = models.CharField(max_length=32,verbose_name='資訊', null=True)
3.直接給欄位設定預設值 
    hobby = models.CharField(max_length=32,verbose_name='愛好', default='play')
"""

終端內直接給預設值操作如下圖

切記只要動了資料庫相關的程式碼就必須執行資料庫遷移的兩條命令

******************************************************************
python manage.py makemigrations
python manage.py migrate
******************************************************************
2. 2、欄位的修改
"""直接修改程式碼然後執行資料庫遷移的兩條命令即可"""
2. 3、欄位的刪除
直接註釋掉對應的欄位程式碼,然後執行資料遷移的兩條命令即可
執行完畢後,欄位對應的資料都沒有了

"""
在操作models.py時,一定要細心

執行遷移命令之前一定要檢查一下程式碼
"""

3、資料的增刪改查

3. 1、 查資料
#views.py
def userlist(request):
    # 查詢出user使用者表裡的所有資料.
    # 方式一
    # data = models.User.objects.filter()
    # print(data)

    # 方式二:
    user_queryset = models.User.objects.all()
    
    return render(request, 'userlist.html', locals())
# views.py
from app02 import  models

#res=models.User.objects.filter(username=username)
# user_obj=res[0]

"""
返回值先看成是一個列表套資料物件的格式
也支援索引取值,切片操作,但是不支援負數索引
同樣也不推薦使用索引方式取值
"""

 # 下面這條程式碼等價於 select * from user where username='zhao';
user_obj=models.User.objects.filter(username=username).first()

print(user_obj)
print(user_obj.username)
print(user_obj.password)


filter括號內可以攜帶多個引數,引數與引數之間預設是and關係
可以把filter聯想成MySQL中的where

user_obj=models.User.objects.filter(username=username,password=password).first()
#select * from user where username='zhao' and password=132;

登入功能

# views.py

def login(request):
   
    if request.method == 'POST':
        
        # 獲取使用者的使用者名稱和密碼,然後利用orm操作資料庫,校驗資料是否正確
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 去資料庫中查詢資料
        from app02 import models
        # select * from user where username='zhao';
        user_obj = models.User.objects.filter(username=username).first()

        # < QuerySet[ < User: Userobject(1) >] >  [資料物件1,資料物件2......]
        # print(res)
        
        # user_obj=res[0]
        # print(user_obj)
        # print(user_obj.username)
        # print(user_obj.password)
        if user_obj:
            # 比對密碼是否一致
            if password == user_obj.password:
                return HttpResponse('登入成功')
            else:
                return HttpResponse('密碼錯誤')
        else:
            return HttpResponse('使用者不存在')




    return render(request, 'login.html')
3. 2 、增加資料
#第一種方法  create()
        from app02 import models
        res = models.User.objects.create(username=username, password=password)
        # 返回值就是當前被建立的物件本身
        
        print(res, res.username, res.password)
        
        
 # 第二種方法  物件.save()
        from app02 import models
   		 #生成一個類物件
        user_obj = models.User(username=username, password=password)
        #物件呼叫save方法
        user_obj.save()#儲存資料

註冊功能

# views.py
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 直接獲取使用者資料存入資料庫
        from app02 import models
        res = models.User.objects.create(username=username, password=password)
        # 返回值就是當前被建立的物件本身
        print(res, res.username, res.password)

    # 先給使用者返回已給註冊頁面
    return render(request, 'register.html')
3. 3 、修改資料
  # 修改資料方式一
        # 獲取到使用者想要刪除 的資料id值
   	 	delete_id = request.GET('user_id')
     	models.User.objects.filter(id=edit_id).update(username=username, password=password)
        """
        將filter查詢出來的列表中所有物件全部更新         批量更新
        只修改被修改的欄位
        """
  # 修改資料方式二
		edit_obj = models.User.objects.filter(id=edit_id).first()
        edit_obj.username = username
        edit_obj.password = password
        edit_obj.save()
        """
        方式二當欄位特別多的時候效率很低
        從頭到尾將資料的所有欄位全部更新一遍,無論該欄位是否被修改
        """
3. 4、 刪除資料
# 刪除使用者
def delete_user(request):
    # 獲取到使用者想要刪除 的資料id值
    delete_id = request.GET('user_id')

    # 直接去資料庫找到對應的資料刪除即可
    models.User.objects.filter(id=delete_id).delete()
    """
    批量刪除
    """
    #跳轉到展示頁面
    return redirect('/userlist/')

真正刪除資料是要有二次確認的,
刪除資料內部其實不是真正的刪除,我們會給資料新增一個標識欄位用來標識當前資料是否被刪除,如果刪除了,僅僅是將一個欄位修改了一個狀態
3.5、示例
#先將資料庫中的資料全部展示到前端,然後給一個數據兩個按鈕,一個編輯,一個刪除

#編輯功能
	#點選編輯按鈕,朝後端傳送編輯資料的請求
   """如何告訴後端使用者想要編輯哪條資料?
   		將編輯按鈕所在的那一行資料的主鍵值傳送給後端
   			利用url問號後面攜帶引數的方式
   """ 
    #後端查詢出使用者想要編輯的資料物件,展示到前端頁面,供使用者檢視和編輯
 #刪除功能
	將資料從前端頁面刪除
  • 資料展示到前端頁面
<!-- userlist.html---> 

<h2 class="text-center">資料展示</h2>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-offset-2">
            <table class="table table-striped table-hover ">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>username</th>
                    <th>password</th>
                    <th class="text-center">action</th>
                </tr>
                </thead>
                <tbody>
                {% for user_obj in user_queryset %}
                    <tr>
                        <td>{{ user_obj.id }}</td>
                        <td>{{ user_obj.username }}</td>
                        <td>{{ user_obj.password }}</td>
                        <td class="text-center">
                            <a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">編輯</a>
                            <a href="/delete_user/user_id={{ user_obj.id }}" class="btn btn-danger btn-xs">刪除</a>
                        </td>
                    </tr>

                {% endfor %}

                </tbody>
            </table>
        </div>
    </div>
</div>
# views.py

# 展示使用者列表

def userlist(request):
    # 查詢出user使用者表裡的所有資料.
    # 方式一
    # data = models.User.objects.filter()
    # print(data)

    # 方式二:
    user_queryset = models.User.objects.all()
    
    return render(request, 'userlist.html', locals())
  • 編輯使用者資料
<!-- edit_user.html--->

<h1 class="text-center">編輯</h1>
<div class="container">
    <div class="row">
        <div class="col-md-offset-2 col-md-8">
            <form action="" method="post">
                <p>username:<input type="text" name="username" class="form-control" value="{{ edit_obj.username }}"></p>
                <p>password:<input type="password" name="password" class="form-control" value="{{ edit_obj.password }}"></p>
                <input type="submit" class="btn btn-info btn-block" value="編輯">

            </form>
        </div>
    </div>
</div>
#views.py
from app03 import models
def edit_user(request):
    # 獲取url問號後面的引數
    edit_id = request.GET.get('user_id')
    # 查詢當前使用者想要編輯的資料物件
    edit_obj = models.User.objects.filter(id=edit_id).first()

    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 去資料庫中修改對應的資料內容

        # 修改資料方式一
        # models.User.objects.filter(id=edit_id).update(username=username, password=password)
        """
        將filter查詢出來的列表中所有物件全部更新         批量更新
        只修改被修改的欄位
        """
        # 修改資料方式二
        edit_obj.username = username
        edit_obj.password = password
        edit_obj.save()
        """
        方式二當欄位特別多的時候效率很低
        從頭到尾將資料的所有欄位全部更新一遍,無論該欄位是否被修改
        """

        # 跳轉到資料的展示頁面
        return redirect('/userlist/')

    # 將資料展示到頁面上
    return render(request, 'edit_user.html', locals())


  • 刪除資料
<!-- userlist.html--->  

<a href="/delete_user/user_id={{ user_obj.id }}" class="btn btn-danger btn-xs">刪除</a>
#views.py
# 刪除使用者
def delete_user(request):
    # 獲取到使用者想要刪除 的資料id值
    delete_id = request.GET.get('user_id')

    # 直接去資料庫找到對應的資料刪除即可
    models.User.objects.filter(id=delete_id).delete()
    """
    批量刪除
    """
    #跳轉到展示頁面
    return redirect('/userlist/')

4、orm中建立表關係(外來鍵

"""
表與表關係
	一對多
		models.ForeignKey(to='Publish', on_delete=models.CASCADE)
	多對多
		models.ManyToManyField(to='Author')
	一對一
		models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)

判斷表關係方式:換位思考

"""
# 建立表關係, 先將基表創建出來,然後在新增外來鍵欄位
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='書名')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='價格')
    # 小數總共8位,小數點後佔2位

    """
    圖書和出版社是一對多,並且書是多的一方,所以外來鍵欄位放在書表裡面
    """
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)  # 預設就是與出版社表的主鍵欄位做外來鍵關聯
    """
    如果欄位對應的是ForeignKey,那麼orm會自動在欄位的後面加_id
    如果自己手動的加了_id,那麼orm還是會在後面加_id
    
    """

    """
    圖書 和作者 是多對多的關係,外來鍵欄位建在任意一方即可,推薦建在查詢頻率較高的一方,
    
    """
    authors = models.ManyToManyField(to='Author')
    """
    authors是一個虛擬欄位,主要是用來告訴orm,書籍表與作者表是多對多的關係
    讓orm自動建立第三章關係表
    """


class Publish(models.Model):
    name = models.CharField(max_length=32, verbose_name='出版社')

    addr = models.CharField(max_length=32, verbose_name='地址')


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name='作者名')
    age = models.IntegerField(verbose_name='年齡')

    """
    
    作者與作者詳情是一對一的關係,外來鍵欄位建立在任意放一方都可以,但是建議建立在查詢頻率較高的地方
    
    """
    author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)  # 級聯刪除
    """
    OneToOneFiel也會自動給欄位加_id字尾,不需要自己加
    """


class AuthorDetail(models.Model):
    phone = models.BigIntegerField(verbose_name='電話')
    addr = models.CharField(max_length=32, verbose_name='作者地址')

    
    
"""

orm中如何定義表關係

publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE) 
authors = models.ManyToManyField(to='Author')



ForeignKey與OneToOneField會自動在欄位後面加_id字尾
"""

5、多對多關係的三種建立方式

  • 全自動
#全自動:利用orm自動幫我們建立第三張關係表
class Book(models.Model):
    name=models.CharField(max_length=32)
    authors=models.ManyToManyField(to='Author')
class Author(models.Model):
    name=models.CharField(max_length=32)

    """
   優點:程式碼不需要自己寫,還支援orm提供的第三張關係表的方法:(add,remove,clear,set)
   缺點:第三張關係表擴充套件性極差,(不能額外的新增欄位)
    """
    


  • 純手動
class Book(models.Model):
    name=models.CharField(max_length=32)
    
class Author(models.Model):
    name=models.CharField(max_length=32)
    
class BookToAuthor(models.Model):
    book=models.ForeignKey(to='Book',on_delete=models.CASCADE)
    author=models.ForeignKey(to='Author',on_delete=models.CASCADE)
    
    """
    優點:第三張關係表完全取決於自己進行額外的拓展
    缺點:需要寫程式碼較多,不能使用orm提供的簡單方法:(add,remove,clear)
    
    
    不建議使用該方式
    """
  • 半自動
class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField(to='Author',
                                     through='BookToAuthor',
                                     through_fields=('book', 'author')
                                     )


class Author(models.Model):
    name = models.CharField(max_length=32)


class BookToAuthor(models.Model):
    book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
    author = models.ForeignKey(to='Author', on_delete=models.CASCADE)

    
   """through_fields欄位先後順序:
        第三張表查詢對應的表,需要用到哪個欄位就把哪個欄位放前面,
        也就是說,當前表是誰,就把對應的關聯欄位放前面
        
        
        
        
        半自動可以使用orm的正反向查詢,但是沒有辦法使用add,remove,clear,set這四個方法
    """


# 總結:
    只需要掌握全自動和半自動,半自動擴充套件性高,一般都採用半自動,