首页 > 数据库 >Django之同时新增数据到两个数据库表与同时返回两个表的数据(插拔式)

Django之同时新增数据到两个数据库表与同时返回两个表的数据(插拔式)

时间:2022-10-21 15:56:22浏览次数:55  
标签:插拔 ProjectList name models Django project 表与 id class

  • models:比如有以下三个模型
from django.db import models

"""
基类,其他类继承即可获得对应的字段
""" 
class BaseModel(models.Model):
    updated_tm = models.DateTimeField(auto_now=True)
    created_tm = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True

"""
项目列表
"""
class ProjectList( BaseModel):
    project_id = models.AutoField(help_text="项目ID", primary_key=True)
    project_name = models.SlugField(max_length=128, help_text="项目名称", unique=True)

    class Meta:
        db_table = 'project_list'
        verbose_name = '项目列表信息'
        verbose_name_plural = verbose_name

"""
项目详情
"""
class ProjectDetail(BaseModel):
    project_introduction = models.CharField(max_length=128, help_text="用户简介")
    project_info = models.ForeignKey(to=ProjectList, on_delete=models.DO_NOTHING, db_constraint=False, related_name='user')

    class Meta:
        db_table = project_detail'
        verbose_name = '项目详情信息'
        verbose_name_plural = verbose_name
一、同时新增数据到两个数据库表
  • views
from rest_framework import filters, mixins, generics
from rest_framework.viewsets import GenericViewSet


class ProjectListView(mixins.CreateModelMixin, GenericViewSet):
    queryset = Account.objects.filter(is_delete=0).all().order_by("-created_tm")

def create(self, request, *args, **kwargs):
    # 先定义两个dict 
    project_list_dict = {}
    project_detail_dict = {}

    # 使用 ._meta.get_fields() 获取数据库表的全部字段,再使用field.name获取全部的字段名称,放入各自的dict,不存在的自动忽略掉
    for item in request.data.items():
        if item in [field.name for field in ProjectList._meta.get_fields()]:
            project_list_dict [item[0]] = item[1]
        elif item in [field.name for field in ProjectDetail._meta.get_fields()]:
            project_detail_dict [item[0]] = item[1]

    # 从上面的models可以看到,项目详情与项目列表两张表是有关联的,所以,新增数据的时候,先现在列表,新增成功,生成ID后,再新增详情,并通过ID与列表数据关联起来
    # 检查项目是否存在,项目名称唯一约束,Serializer内设置必填
        try:
            # 存在就直接失败
            ProjectList.objects.get(project_name=request.data.get('project_ame'))
            return xxx
        except Account.DoesNotExist:
            # 如果不存在,先调用ProjectList表新增数据
            try:
                project_create = ProjectList.objects.update_or_create(defaults=project_list_dict, project_name=project_list_dict["project_ame"])
                # 如果ProjectList表新增数据成功,则通过project_info,在ProjectDetail新增对应的数据
                if project_create:
                    project_id = ProjectList.objects.filter(project_name=project_list_dict["project_ame"]).values('project_id').first()
                    ProjectDetail.objects.update_or_create(defaults=project_detail_dict, project_info=project_id["project_id"])
                    return xxx
            except Exception as e:
                return e
二、同时返回两个表的数据(插拔式)
  • 插拔式的好处:即插即用,需要时才调用,不需要则不调用
  • 从ProjectDetail这个models我们可以看到,是没有定义project_id和project_name的,但我们是与ProjectList关联的,所以,我们可以通过project_info,返回ProjectList已定义的project_id和project_name
# 我们只需要把ProjectDetail改成以下这样子就可以了
class ProjectDetail(BaseModel):
    project_introduction = models.CharField(max_length=128, help_text="用户简介")
    project_info = models.ForeignKey(to=ProjectList, on_delete=models.DO_NOTHING, db_constraint=False, related_name='user')

    class Meta:
        db_table = project_detail'
        verbose_name = '项目详情信息'
        verbose_name_plural = verbose_name

    @property
    def  project_id(self):
        return self.project_info.project_id

    @property
    def  project_name(self):
        return self.project_info.project_name

# 然后在序列化器内直接调用project_id和project_name即可
class ProjectDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProjectDetail

        fields = ('project_id', 'project_name', 'project_introduction',)

标签:插拔,ProjectList,name,models,Django,project,表与,id,class
From: https://www.cnblogs.com/lsc-blog/p/16813732.html

相关文章

  • django--各个文件的含义
    当你创建项目或者应用后你是不是发现多了很多个文件,现在我们来看看各代表什么意思与你项目名相同的文件夹:是项目的管理功能目录,这个目录的名称因用户所创建的项目名称的不......
  • django迁移文件的问题
    如果数据库中已经有需要通过迁移文件才能生成的数据表,在再执行迁移文件生成的话会提示已经有这个库了方案1:删除数据表或数据库方案2:找到数据库中django_migrations......
  • Django 跨域CORS
    解决后端对跨域访问的支持。安装pipinstalldjango-cors-headers注册应用INSTALLED_APPS=[...,corsheaders,...]中间件设置MIDDLEWARE=[......
  • Django自定义URL转换器
    http://127.0.0.1:8000/usernames/zhangsan/count/以上URL请求传递参数username,此username需进行校验,不满足条件,不需要进入视图进行验证,减少数据库调用。可自定义转换......
  • 字段加密实践(django-fernet-fields)
    一、fernet介绍Fernet用于django模型字段对称加密,使用crytography库。官网帮助文档1、先决条件django-fernet-fields支持Django1.8.2以及更高版本,Python2.7、3......
  • Django启动问题大杂烩
    1.ProgrammingErrorat/admin/login/(1146,"Table'mes.auth_user'doesn'texist") 解决办法:输入命令:pythonmanage.pymigrate   更新数据库表单......
  • 记录python3.7版本中 Django+celery 启动报错
     虚拟环境启动I报错Traceback(mostrecentcalllast):File"/data/.virtualenvs/cmdb/lib/python3.7/site-packages/gunicorn/arbiter.py",line589,inspawn_w......
  • Django初始化创建用户名
    (venv)D:\project\py37project\Djangopro\Procrm>Pythonmanage.pycreatesuperuser  #这是创建Django初始化用户名跟密码的一个命令。示例如下:Username(leavebla......
  • Django Rest Framework中文文档:Serializer relations
    这是对DRF官方文档:Serializerrelations的翻译,根据个人的理解对内容做了些补充、修改和整理。一,django模型间的关系在我们对数据进行建模时,最重要的一点就是根据功能需求......
  • Django环境搭建
    1、安装Django,进入到python安装目录的scripts目录下,使用命令pip3installdjango2、创建Django项目,使用命令django-adminstartproject项目名称,就会在指定文件夹下生成Djan......