Django模型层(1)模型介绍

文章目录

  • 模型
    • 快速上手定义一个模型
    • 使用模型
    • 字段
      • 字段选项
        • choices
        • primary_key
      • 字段备注名
    • 关联关系
      • 多对一关联
      • 多对多

模型

模型准确且唯一的描述了数据。它包含您存储的数据的重要字段和行为。一般来说,每一个模型都映射一张数据库表。

  • 每个模型都是一个Python的类,这些类继承于django.db.models.Model
  • 每个模型类的属性都相当于一个数据库的字段。

快速上手定义一个模型

这个样例定义了一个Person模型,拥有first_name和last_name两个类属性。

from django.db import models


class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

first_name和last_name是模型的字段,每个字段都被指定为一个类属性,并且每个属性映射为一个数据表列。

上面的Person模型会创建如下一张数据库表:

create table my_model_person
(
    id         int         not null primary key generated by default as identity,
    first_name varchar(30) not null,
    last_name  varchar(30) not null
);
  • 该表的名称 my_model_person 是自动从app名提炼出来的,my_model是该模型的app。
  • id是dj自动添加的,可以手动添加。

使用模型

一旦你定义了你的模型,你需要告诉Django你准备使用这些模型了。需要修改设置文件中的INSTALLED_APPS,在这个设置中添加包含models.py文件的模块名称

INSTALLED_APPS = [
    ...
    "myapp"
    ...
]

如果使用的不是默认的是Mysql数据库还需要在设置中修改DATABASES

DATABASES = {
    'default': {
        # django数据库引擎
        'ENGINE': 'django.db.backends.mysql',
        # 数据库名
        'NAME': 'you_database_name',
        # 用户名
        'USER': 'root',
        # 登录密码
        'PASSWORD': '123456',
        # 数据库ip
        'HOST': 'localhost',
        # 端口
        'POST': '3306'
    }
}

添加结束后进行数据库的迁移

# 检查app下migrations和models是否有更新
python manage.py makemigrations

# 执行修改
python manage.py migrate

字段

模型中最重要且唯一必要的是数据库的字段定义。字段在类属性中定义。定义字段名时要避免使用与模型API冲突的名称,例如:
clean,save,delete等。

from django.db import models


class Musician(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    instrument = models.CharField(max_length=100)


class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

模型中每一个字段都对应时某个Field类的实例,Django利用这些字段来实现对数据库的操作:

  • 字段类型用以指定数据库数据类型
  • 基本的有效性验证功能,用于Django后台和自动生成的表单

字段选项

每一种字段都需要指定一些特定的参数。例如 CharField需要接受一个max_length参数,用以指定数据库存储VARCHAR数据时用的字节数

一些可选参数是通用的,可用于任何类型的字段

  • null
    • 如果设置为True,则该字段可为空。默认为False。
  • default
    • 该字段的默认值。可以是一个值或是个可调用的对象,如果是个可调用的对象,每次实例化模型的时候都会调用该对象
  • unique
    • 如果设置为True,则该字段的值在整个表中必须保持唯一

choices

  • 一些列二元组,用作此字段的选项。如果提供了二元组则会限制存入的数据。

例如

from django.db import models


class Person(models.Model):
    SHIRT_SIZES = [
        ('S', "Small"),
        ('M', "Medium"),
        ('L', "Large")
    ]
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES, null=True)

打开交互测试环境:python manage.py shell

from my_model.models import Person
p = Person(first_name="z",last_name="zj",shirt_size="M")
p.save()
p.shirt_size
'M'
p.get_shirt_size_display()
'Medium'

primary_key

如果设置为True,将该字段设置为该模型的主键

主键为只可读,如果你修改一个记录的主键并保存,这等同于你创建了一个新的记录。

class Fruit(models.Model):
    name = models.CharField(max_length=100, primary_key=True)
from my_model.models import Fruit
fruit = Fruit(name="1")
fruit.save()
fruit.name
'1'
fruit.name = "2"
fruit.save()
fruit.name
'2'
Fruit.objects.values_list("name",flat=True) 


自增主键

class Animal(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=100)
from my_model.models import Animal
# 指定id
a = Animal(id=1,name="dog")
a.name
'dog'
# 不指定id
a = Animal(name="cat")
a.save()
# 从表中拿到所有记录对象
Animal.objects.all()
, ]>
# 从表中拿到所有name的值
Animal.objects.values_list("name")  

Animal.objects.values_list("name",flat=True) 

# 从表中拿到所有id的值
Animal.objects.values_list("id",flat=True)   
# 自增没有问题

字段备注名

first_name = models.CharField("person's first name",max_length=30)

关联关系

关系型数据库的强大之处在于各个表之间的关联关系。Django提供了定义三种最常见的数据库关联方法:多对一,多对多,一对一

多对一关联

定义一个多对一的关联关系,使用 ForeignKey

class Musician(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    instrument = models.CharField(max_length=100)

class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

使用shell测试

# 成功保存 create会帮我们直接保存数据
from my_model.models import Musician,Album
m = Musician.objects.create(first_name="1",last_name="2",instrument="3")
a = Album.objects.create(name="4",release_date="2022-10-10",num_stars=5,artist=m)

# 以下操作报错,应为m没有保存就直接作为了a的参数传入
m = Musician(first_name="1",last_name="2",instrument="3")                
a = Album(name="4",release_date="2022-10-10",num_stars=5,artist=m)  
a.save()
Traceback (most recent call last):
  File "", line 1, in 
  File "C:\Users\g1712\.conda\envs\attend-classclass-begins\lib\site-packages\django\db\models\base.py", line 778, in save
    self._prepare_related_fields_for_save(operation_name="save")
  File "C:\Users\g1712\.conda\envs\attend-classclass-begins\lib\site-packages\django\db\models\base.py", line 1093, in _prepare_related_fields_for_save
    raise ValueError(
ValueError: save() prohibited to prevent data loss due to unsaved related object 'artist'.

# 也可以这样写
m = Musician(first_name="1",last_name="2",instrument="3")           
m.save()
a = Album(name="4",release_date="2022-10-10",num_stars=5,artist=m)  
a.save()
m = Musician.objects.create(first_name="1",last_name="2",instrument="3")

自关联

公司成员都有上级领导,在prent_id中记录的就是上级领导的id

class Member(models.Model):
    member_id = models.AutoField(primary_key=True)
    prent_id = models.ForeignKey('self', db_column='prent_id', to_field='member_id', on_delete=models.CASCADE)

多对多

披萨、配料对应表

class Pizza(models.Model):
    pizza_id = models.AutoField(primary_key=True)
    name = models.CharField()


class Topping(models.Model):
    topping_id = models.AutoField(primary_key=True)
    name = models.CharField()


class PizzaToppingMapping(models.Model):
    pizza_topping_mapping_id = models.AutoField(primary_key=True)
    pizza_id = models.ForeignKey(Pizza, on_delete=models.CASCADE)
    topping_id = models.ForeignKey(Topping, on_delete=models.CASCADE)

使用shell测试

from my_model.models import Pizza,Topping,PizzaToppingMapping
# 添加
p = Pizza.objects.create(name="奥尔良鸡翅烤肉披萨")
t = Topping.objects.create(name="奥尔良鸡翅")
t1 = Topping.objects.create(name="烤肉")       
t2 = Topping.objects.create(name="芝士")      
pt = PizzaToppingMapping.objects.create(pizza_id=p,topping_id=t)  
pt = PizzaToppingMapping.objects.create(pizza_id=p,topping_id=t1) 

你可能感兴趣的:(Django,django,python,后端)