今天要來講當Model裡面新增欄位和屬性的用法
當我們需要在Model裡面更新新的欄位時,不像建立的時候可以不給值,他會要求你幫該欄位預設一個值。
可以看到下面範例的錯誤訊息
當我加入一個 makedate = models.DateField()
他會報錯說沒辦法加一個 non-nullable field, 在沒有預設值的情況下。
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 他不只可以限制大小也能確認所傳送的資料類型是否正確
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