博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Django基础 - 04Model模型之字段类型与元数据

Posted on 2023-04-08 20:28  Kingdomer  阅读(115)  评论(0编辑  收藏  举报

 

Model(模型): 用来与数据做交互(读取和写入数据)

ORM: 对象关系映射 Object Relational Mapping; Python中的Model对象和数据库的表做映射

 

一、 字段类型

1.1 字段类型介绍

CharField
IntegerField        数值类型;  choice:枚举类型的数据,元祖的元祖
BooleanField
NullBooleanField
AutoField           int自增列,必须填入参数primary_key=True; auto_create,自动创建
FloatField
DecimalField        同Python的Decimal类型;参数:max_digits最大总位数 decimal_places小数点后的位数
TextField
UUIDField
FileField     字符串,路径保存在数据库,文件上传到指定目录
              参数: upload_to="";  storage=None  存储组件,默认django.core.files.storage.FileSystem
ImageField    字符串,路径保存在数据库,文件上传到指定目录
              upload_to=""; storage=None 默认django.core.files.storage.FileSystem
              width_field=None  上传图片的高度保存的数据库字段名(字符串)
              height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DateField     日期类型; 格式:YYYY-MM-DD    参数: auto_now; auto_now_add
DateTimeField 日期时间类型datetime.datetime   日期+时间格式 YYYY-MM-DD HH:MM:ss.uuuuuu[TZ]

  

1.2  StoreEntity 模型类

1.2.1 编写 mainapp/models.py, 创建 StoreEntity 

class StoreEntity(models.Model):
    # 默认,模型自动创建主键id, 也可以显式声明主键
    id = models.UUIDField(primary_key=True, verbose_name='店号', defaults=uuid.uuid4().hex)
    name = models.CharField(max_length=50, verbose_name='店名', unique=True)
    store_type = models.IntegerField(choices=((0, '自营'), (1, '第三方')), verbose_name='类型', db_column='type_')
    address = models.CharField(max_length=100, verbose_name='地址')
    city = models.CharField(max_length=50, verbose_name='城市', db_index=True) 

    create_time = models.DateField(verbose_name='成立时间', auto_now_add=True, null=True)
    last_time = models.DateField(verbose_name='最后变更时间', auto_now=True, null=True)

    def __str__(self):
        return self.name + '-' + self.city

    class Meta:
        db_table = 't_store'
        verbose_name = '店铺管理'
        verbose_name_plural = verbose_name
        unique_together = (('name', 'city'), )

 

1.2.2 查看数据库的表结构

 

create table t_store
(
    id             char(32)   not null  primary key,
    name        varchar(50)   not null  unique,
    type_           INTEGER   not null,
    address    varchar(100)   not null,
    city        varchar(50)   not null,
    create_time       date,
    last_time         date
);

create index t_store_city_64bd4797  on t_store (city);

create unique index t_store_name_city_1218e539_uniq on t_store (name, city);

 

1.2.3 django_migrations 表数据

 

1.2.4 编写 mainapp/admin.py, 后台管理配置

class StoreAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'city', 'address', 'store_type')
    fields = ('name', 'city', 'address', 'store_type')  # 指定表单修改的字段

admin.site.register(StoreEntity, StoreAdmin)

 

 

1.2.5 后台管理类配置 fieldsets实现分栏显示

ERRORS: # fields 和 fieldsets 不能同时配置
<class 'mainapp.admin.StoreAdmin'>: (admin.E005) Both 'fieldsets' and 'fields' are specified.

 

class StoreAdmin(admin.ModelAdmin):
    list_display = ('id_', 'name', 'city', 'address', 'store_type', 'logo', 'summary')
    # fields = ('name', 'city', 'address', 'store_type', 'logo', 'summary')
    fieldsets = (['Main', {'fields': ('name',)}],
                 ['Advance', {'fields': ('address',), 'classes': ('collapse',)}])

 

 

1.3 UUID类型字段

ModelAdmin 和 ModelForm提供了对UUID格式的验证

1.3.1 使用save()保存 UUID类型的 id字段

    id = models.UUIDField(primary_key=True, verbose_name='店号')

    # 调用模型保存方法时被调用
    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        # 判断是否为新增
        if not self.id:
            self.id = uuid.uuid4().hex
        super().save()

 

1.3.2 UUID类型字段显示带中划线问题

uuid.uuid4()       e5b33241-dd89-4689-8a17-612631cd41be
uuid.uuid4().hex   74a41463c54c4b619d90e597dbbb5b36

 

class StoreEntity(models.Model):

    @property
    def id_(self):
        # return str(self.id).replace('-', '')   # 方法一
        return self.id.hex                       # 方法二

class StoreAdmin(admin.ModelAdmin): 
list_display = ('id_', 'name', 'city', 'address', 'store_type') # 展示字段改成 id_

  

1.4 FileField 和 ImageField

文件字段和图片字段 都是MEDIA的多媒体类型的文件, 需要在 settings.py 指定 MEDIA_ROOT、MEDIA_URL、STATIC_URL、STATICFILES_DIRS
# 模型类中使用上传文件的字段, 文件访问路径是相对MEDIA
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

  

1.4.1 编写 helloDjango/urls.py

from django.conf.urls.static import static

urlpatterns = [ ...... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

1.4.2 编写 heloDjango/mainapp/models.py

    logo = models.ImageField(verbose_name='LOGO', upload_to='store',
                             width_field='logo_width', height_field='logo_height',
                             null=True, blank=True)

    logo_width = models.IntegerField(verbose_name='LOGO宽', null=True)
    logo_height = models.IntegerField(verbose_name='LOGO高', null=True)

    summary = models.TextField(verbose_name='介绍', blank=True, null=True)
    opened = models.BooleanField(verbose_name='是否开业', default=False)

  

1.4.3 安装Pillow

ERRORS:
mainapp.StoreEntity.logo: (fields.E210) Cannot use ImageField because Pillow is not installed.
        HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "pip install Pillow".
(venv) E:\PythonLearn\djangoDemo\helloDjango>pip install Pillow

  

 

 

1.5 字段约束

max_legth 最大长度 / default 默认值 / unique 唯一 / primary_key / null / blank /

db_index 索引 / db_column / verbose_name / choices

 

二、Meta元信息

在模型类中, 声明内部类Meta, 类成员变量包括:

  • db_table / ordering / verbose_name / verbose_name_plural / unique_together
  • abstract: 布尔类型, 表示当前的模型类是否为抽象类, 如果是抽象类, 则不会创建表

2.1 编写 mainapp/apps.py

from django.apps import AppConfig

class MainappConfig(AppConfig):
    name = 'mainapp'
    app_label = '主模块'

 

2.2 在Model模型类定义Meta信息

class CategoryEntity(models.Model):

    class Meta:
        app_label = 'mainapp'
        db_table = 't_category'
        ordering = ['-order_num']  # 排序字段,- 表示降序
        verbose_name = '水果分类'
        verbose_name_plural = verbose_name