1. 程式人生 > 其它 >Django的ORM單表操作

Django的ORM單表操作

ORM介紹

  什麼是ORM

    物件關係對映(英語:Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程式設計技術,用於實現面向物件程式語言裡不同型別系統的資料之間的轉換。

  ORM特點

    在操作資料庫的時候,不用在寫原生SQL語句,相對而言,執行效率低了。

  書寫位置

    在models.py檔案中

  對應關係

    類名 >>> 表名
    物件 >>> 記錄
    屬性 >>> 欄位

ORM建立表

  1.在models.py中書寫一個類

class User(models.Model):
    id = models.AutoField(primary_key=True)
    # 等價於id int primary_key auto_increment
    username = models.CharField(max_length=32)
    # 等價於username varchar(32)
    password = models.IntegerField()
    # 等價於password int

  注意:由於一張表中必須要有一個主鍵欄位 並且一般情況下都叫id欄位

     所以ORM當你不定義主鍵欄位的時候會自動幫你建立一個名為id主鍵欄位(如果是別的想用別的欄位名就必須自己建立)

     CharField必須要指定max_length引數 不指定會直接報錯

  2.執行資料庫遷移命令

python3 manage.py makemigrations

python3 manage.py migrate

    注意:只要你修改了models.py中跟資料庫相關的程式碼 就必須重新執行上述的兩條命令

欄位的增刪改查

  新增欄位

    新增欄位可以在類體程式碼中直接新增即可。

class User(models.Model):
    id = models.AutoField(primary_key=True)
    # 等價於id int primary_key auto_increment
username = models.CharField(max_length=32) # 等價於username varchar(32) password = models.IntegerField() # 等價於password int info = models.CharField(max_length=32)

    但是如果資料表中已經有了資料,那麼新增欄位就需要解決原有記錄的資料問題

    解決方式:

      1.在終端中輸入預設值

      2.設定該欄位可以為空

 info = models.CharField(max_length=32,null=True)

      3.直接設定預設值

 hobby = models.CharField(max_length=32,default='study')

  欄位的修改

    直接修改程式碼然後執行資料庫遷移的兩條命令即可

  欄位的刪除

    直接註釋對應的欄位然後執行資料庫遷移的兩條命令即可

    注意:執行完畢之後欄位對應的資料也就都被刪除了

資料的增刪改查

  為方便學習簡單的建立一個HTML網頁通過按鈕實現增刪改查的功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1 class="text-center">列表展示</h1>
        <a href="/add/" class="btn btn-success btn-lg">新增資料</a>
        <table class="table table-striped table-hover">
            <thead>
            <tr>
                <th>ID</th>
                <th>UserName</th>
                <th>PassWord</th>
                <th>operate</th>
            </tr>
            </thead>
            <tbody>
                {% for user in user_list %}
                    <tr>
                        <td>{{ user.id }}</td>
                        <td>{{ user.username }}</td>
                        <td>{{ user.password }}</td>
                        <td>
                            <a href="/edit/?id={{ user.id }}" class="btn btn-primary">修改</a>
                            <a href="/delete/?id={{ user.id }}" class="btn btn-danger">刪除</a>
                        </td>
                    </tr>
                {% endfor %}

            </tbody>
        </table>
    </div>
</div>
</body>
</html>
userlist.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
 <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1 class="text-center">新增資料</h1>
        <form action="" method="post">
            <div class="form-group">
                username:
                <input type="text" name="username" class="form-control">
            </div>
            <div class="form-group">
                password:<input type="password" name="password" class="form-control">
            </div>

            <input type="submit" value="提交" class="btn btn-success btn-block">
        </form>
    </div>
</div>
</body>
</html>
add.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1 class="text-center">修改資料</h1>
        <form action="" method="post">
            <div class="form-group">
                username:
                <input type="text" name="username" class="form-control" value="{{ edit_obj.username }}">
            </div>
            <div class="form-group">
                password:<input type="password" name="password" class="form-control" value="{{ edit_obj.password }}">
            </div>

            <input type="submit" value="提交" class="btn btn-success btn-block">
        </form>
    </div>
</div>
</body>
</html>
edit.html

  資料的增加

    

def add(request):
# 判斷請求方式
    if request.method == 'POST':
# 獲取頁面傳送的資料
        username = request.POST.get('username')
        password = request.POST.get('password')
# 新增資料
        models.User.objects.create(username=username, password=password)
# 返回頁面
        return redirect('/index/')
    return render(request, 'add.html')


# 第二種方式
user_obj = models.User(username=username,password=password)
user_obj.save()  # 儲存資料

  資料的查詢

def show_list(request):
# 查詢所有
    user_list = models.User.objects.all()
    return render(request, 'userlist.html', locals())


# 查詢第一條
models.User.objects.filter(id=id).first()
# filter相當於sql語句中的where,多個條件相當於用and連線

  資料的修改

def edit(request):
    # 獲取傳送的id
    id = request.GET.get('id')
    # 根據id查詢資料
    edit_obj = models.User.objects.filter(id=id).first()
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
       # 修改資料
        models.User.objects.filter(id=id).update(username=username, password=password)
        return redirect('/index/')
    return render(request, 'edit.html', locals())

  資料的刪除

def delete(request):
    # 獲取id
    id = request.GET.get('id')
    # 刪除資料
    models.User.objects.filter(id=id).delete()
    return redirect('/index/')

ORM建立表關係

  以圖書表,出版社表,作者表,作者詳情表為例

  一對多

# 建立表關係  先將基表創建出來 然後再新增外來鍵欄位

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

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    # 總共八位 小數點後面佔兩位
    """
    圖書和出版社是一對多 並且書是多的一方 所以外來鍵欄位放在書表裡面
    """
    publish = models.ForeignKey(to='Publish')  # 預設就是與出版社表的主鍵欄位做外來鍵關聯
    """
    如果欄位對應的是ForeignKey 那麼會orm會自動在欄位的後面加_id
    如果你自作聰明的加了_id那麼orm還是會在後面繼續加_id
    
    後面在定義ForeignKey的時候就不要自己加_id
    """

  多對多

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

  一對一

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    """
    作者與作者詳情是一對一的關係 外來鍵欄位建在任意一方都可以 但是推薦你建在查詢頻率較高的表中
    """
    author_detail = models.OneToOneField(to='AuthorDetail')
    """
    OneToOneField也會自動給欄位加_id字尾
    所以你也不要自作聰明的自己加_id
    """

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()  # 或者直接字元型別
    addr = models.CharField(max_length=32)