iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0

前言

今天要來講當Model裡面新增欄位和屬性的用法

更新 Model

當我們需要在Model裡面更新新的欄位時,不像建立的時候可以不給值,他會要求你幫該欄位預設一個值。
可以看到下面範例的錯誤訊息
當我加入一個 makedate = models.DateField()
他會報錯說沒辦法加一個 non-nullable field, 在沒有預設值的情況下。

models.py

class Product(models.Model):
    Product_name = models.CharField(max_length=30)
    price = models.IntegerField(default=0)
    makedate = models.DateField()
    def __str__(self) -> str:
        return f"{self.Product_name}'s price is {self.price}"
python manage.py makemigrations Django_app
It is impossible to add a non-nullable field 'makedate' to product without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit and manually define a default value in models.py.
Select an option:

解決方法可以簡單使用default就能解決了

from django.db import models
from datetime import date

class Product(models.Model):
    Product_name = models.CharField(max_length=30)
    price = models.IntegerField(default=0)
    makedate = models.DateField(default = date.today)
    def __str__(self) -> str:
        return f"{self.Product_name}'s price is {self.price}"

Validator

除此以外也能夠用validator,來限制我們欄位的大小。
用法可以參考官方文件
Validator 他不只可以限制大小也能確認所傳送的資料類型是否正確

from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from datetime import date

class Product(models.Model):
    Product_name = models.CharField(max_length=30)
    price = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(9999999)])
    makedate = models.DateField(default = date.today)
    makenum = models.IntegerField(default = 0, validators=[MinValueValidator(0), MaxValueValidator(9999999)])
    def __str__(self) -> str:
        return f"{self.Product_name}'s price is {self.price}"

接著我們可以來到migrations裡面查看我們生成的資料欄位
可以看到當我們新建新的欄位時就會顯示 AlterField
在舊有欄位更新欄位就會顯示 AddField
可以用此方式來查看自己更動的東西以及是否正確

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('Django_app', '0002_product_makedate'),
    ]

    operations = [
        migrations.AddField(
            model_name='product',
            name='makenum',
            field=models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(9999999)]),
        ),
        migrations.AlterField(
            model_name='product',
            name='price',
            field=models.IntegerField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(9999999)]),
        ),
    ]

記得更新完欄位後,要migration,才會更新完成唷

更新資料

在Django裡,他提供了很簡單的方法,讓我們可以快速又簡單的更新資料
首先我們一樣先打開python shell

(django_env) PS C:\Users\Yusin\Django_website\Django_project> python manage.py shell  
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

接著用一樣的方式

先import Model裡的class

In [6]: from Django_app.models import Product

接著我們用get看一下pk1目前的資料

In [7]: Product.objects.get(pk=1)
Out[7]: <Product: ToyCar's price is 20>

接著我們讓一個變數去接收他

In [8]: toy = Product.objects.get(pk=1)

之後我們就直接更動他在save(),更新資料就完成了!

In [9]: toy.Product_name = "sunny"

In [10]: toy
Out[10]: <Product: sunny's price is 20>

In [11]: toy.save()

In [12]: Product.objects.get(pk=1)
Out[12]: <Product: sunny's price is 20>

刪除資料

刪除資料和更新資料很像
差別在於save() 改成 delete()
我們一樣設一個變數去接收我們要刪除的資料

In [8]: toy = Product.objects.get(pk=1)

In [9]: toy.delete()
Out[9]: (1, {'Django_app.Product': 1})

當我們重新查詢資料庫時,就會發現他被刪除了!

In [18]: Product.objects.all()
Out[18]: <QuerySet [<Product: ToyCar's price is 20>, <Product: Computer's price is 20000>, <Product: bike's price is 2000>, <Product: pen's price is 20>, <Product: light's price is 200>, <Product: mouse's price is 2200>, <Product: pen's price is 20>, <Product: light's price is 200>, <Product: ToyCar's price is 1000>]>

參考資料&推薦閱讀

https://docs.djangoproject.com/en/4.1/ref/models/instances/#django.db.models.Model.delete


上一篇
Day-22 - Models - Shell 的查找
下一篇
Day-24 - Model- 連結Template
系列文
從0 到 50 初探 如何使用Django 架構出一個網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言