Django两表案例

本文详细介绍了使用Django框架实现主从表的交互功能,包括创建模型、数据库配置、路由分发、视图处理及模板设计。通过实例展示了如何展示主表数据、跳转至子表页面、添加子表数据、删除和更新子表数据的操作流程。此外,还强调了理解代码含义、处理错误和页面跳转的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.思路

  1. 配置两个表的模型,主表、子表(注意:外键)
  2. 展示主表数据
  3. 点击主表名称 => 跳转到相应的子表页面
  4. 在主表内创造添加子表数据功能,能够添加成功
  5. 子表内有删除、更新操作(链接)
  6. 点击删除链接,能够删除数据,并跳转到原来的子表页面
  7. 点击更新链接 => 添转到更新页面 => 点击更新跳转到相应的子表页面

2.准备工作

1)创建新的项目
django-admin startproject 项目名
2) 创建子应用
python manage.py startapp 应用名
3) 配置setting.py
# 注册子应用
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'employee',
]

# 配置模板
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'tem')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# 配置数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST':'localhost',
        'POST':3306,
        'USER':'root',
        'PASSWORD':'123123',
        'NAME':'emp',
    }
}

# 配置语言、时区
LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'
4) 安装数据库

在项目名对应的文件夹下的init文件

import pymysql
pymysql.install_as_MySQLdb()

3. 创建模型类

1)创建模型

:注意主表和子表的先后顺序、注意外键的添加

from django.db import models

# Create your models here.

# 创建主模型,部门模型
class Department(models.Model):
    dep_name = models.CharField(max_length=20,verbose_name='部门名称')
    desc = models.CharField(max_length=50,verbose_name='部门描述')
 	# 元类
    class Meta:
        verbose_name = '部门表'
        verbose_name_plural = verbose_name
        db_table = 'department'
    def __str__(self):
        return self.dep_name

# 创建子模型,员工模型
class Employee(models.Model):
    emp_name = models.CharField(max_length=20,verbose_name='姓名')
    job = models.CharField(max_length=20,verbose_name='职位')
    salary = models.IntegerField(default=3000,verbose_name='工资')
    department = models.ForeignKey(to=Department,on_delete=models.CASCADE,verbose_name='部门')
    class Meta:
        verbose_name = '员工表'
        verbose_name_plural = verbose_name
        db_table = 'employee'
    def __str__(self):
        return self.emp_name
2)注册表

在admin文件

from django.contrib import admin
from employee.models import Department,Employee
# Register your models here.
admin.site.register(Department)
admin.site.register(Employee)
3) 执行迁移、生成迁移
python manage.py makemigrations

python manage.py migrate
4) 注册超级用户,添加信息
python manage.py createsuperuser

在admin网址,自己添加信息

5)路由分发

主路由

from django.contrib import admin
from django.urls import path,include
from employee import urls,views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include(urls)),  # 路由分发
]

子路由 在子应用文件夹下创建urls py文件

from django.urls import path
from employee import views
urlpatterns = [
    path('dep/',views.DepView.as_view()), # 部门视图
    # 动态路由,根据部门编号,获取员工信息
    path('emp/<int:id>/',views.EmpView.as_view()),# 员工视图
    # 动态路由,根据员工id删除员工信息
    path('del/<int:id>/',views.DelView.as_view()),# 删除视图
    path('update/<int:id>/',views.UpdateEmpView.as_view()), # 更新视图
]

4 功能

1) 展示主表部门表页面

视图

from django.shortcuts import render,redirect
from django.views import View
from django.http import HttpResponse
from employee.models import Department,Employee

class DepView(View):
    # 获取部门页面,并展示部门信息
    def get(self,request):
        # 获取信息
        departments = Department.objects.all()
        # 跳转页面传递信息
        return render(request,'dep.html',{'deps':departments})
    # 添加员工信息
    def post(self,request):
        # 解析post请求数据
        name = request.POST.get('name')
        job = request.POST.get('job')
        salary = request.POST.get('salary')
        dep = request.POST.get('dep')
        try:
            # 添加信息
            Employee.objects.create(
                emp_name=name,job=job,salary=salary,department_id=dep
            )
        except Employee as e:
            print(e)
            return HttpResponse('添加失败')
        # 重定向到部门页面
        return redirect('/dep/')

路由

path('dep/',views.DepView.as_view()), # 部门视图

部门页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h3>部门页面</h3>
    <table width="400px" border="1px">
        <tr>
            <th>编号</th>
            <th>部门名称</th>
            <th>部门描述</th>
        </tr>
        {% for dep in deps %}
            <tr>
                <th>{{ dep.id }}</th>
                {#  点击部门名称传递部门编号跳转到相应的员工信息 #}
                <th><a href="/emp/{{ dep.id }}/">{{ dep.dep_name }}</a></th>
                <th>{{ dep.desc }}</th>
            </tr>
        {% endfor %}
    </table><br/>
    <form method="post">
        {% csrf_token %}
        姓名:<input type="text" name="name">
        职位:<input type="text" name="job">
        工资:<input type="text" name="salary">
        部门编号:<input type="text" name="dep">
        <input type="submit" value="添加">
    </form>
</body>
</html>
2)子表,展示员工表信息

视图

class EmpView(View):
    # 根据部门id,展示员工信息
    def get(self,request,id):
        # 查找对应部门编号的员工信息
        emp_data = Employee.objects.filter(department_id=id)
        return render(request,'emp.html',{'emps':emp_data})

路由

# 动态路由,根据部门编号,获取员工信息
    path('emp/<int:id>/',views.EmpView.as_view()),# 员工视图

子表页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h3>员工信息</h3>
    <table width="500px" border="1px">
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>职位</th>
            <th>工资</th>
            <th>部门</th>
            <th>操作</th>
        </tr>
        {% for emp in emps %}
            <tr>
                <th>{{ emp.id }}</th>
                <th>{{ emp.emp_name }}</th>
                <th>{{ emp.job }}</th>
                <th>{{ emp.salary }}</th>
                <th>{{ emp.department_id }}</th>
                <th>
                    <a href="/del/{{ emp.id }}/">删除</a>
                    <a href="/update/{{ emp.id }}/">更新</a>
                </th>
            </tr>
        {% endfor %}

    </table>
</body>
</html>
3) 删除功能

视图

class DelView(View):
    def get(self,request,id):
        # 根据员工id,删除信息
        # 方式一,重定向到部门页面
        # Employee.objects.filter(id=id).delete()
        # return redirect('/dep/')

        # 方式二,重定向到员工页面
        emp_data = Employee.objects.get(id=id)
        # 保存部门id,用于重定向
        emp_id = emp_data.department_id
        # 删除数据
        emp_data.delete()
        # 格式化重定向
        return redirect(f'/emp/{emp_id}/')

路由

# 动态路由,根据员工id删除员工信息
    path('del/<int:id>/',views.DelView.as_view()),# 删除视图
3)更新功能

视图

class UpdateEmpView(View):
    # 获取员工信息更新页面,并根据id,在表单中展示信息
    def get(self,request,id):
        emp_data = Employee.objects.get(id=id)
        return render(request,'index.html',{'emp':emp_data})
    def post(self,request,id):
        name = request.POST.get('name')
        job = request.POST.get('job')
        salary = request.POST.get('salary')
        dep = request.POST.get('dep')
        try:
            emp_data = Employee.objects.get(id=id)
            emp_id = emp_data.department_id
            emp_data.emp_name=name
            emp_data.job=job
            emp_data.salary=salary
            emp_data.department_id=dep
            emp_data.save()
        except Employee as e:
            print(e)
            return HttpResponse('更新失败')
        return redirect(f'/emp/{emp_id}/')

路由

path('update/<int:id>/',views.UpdateEmpView.as_view()), # 更新视图

更新页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h3>更新员工信息</h3>
     <form method="post">
        {% csrf_token %}
        姓名:<input type="text" name="name" value="{{ emp.emp_name }}">
        职位:<input type="text" name="job" value="{{ emp.job }}">
        工资:<input type="text" name="salary" value="{{ emp.salary }}">
        部门编号:<input type="text" name="dep" value="{{ emp.department_id }}">
        <input type="submit" value="修改">
    </form>
</body>
</html>

总结

  1. 想清思路,知道每句代码的含义
  2. 报错看清报错信息,找到错误位置改正
  3. 知道每部该跳转到哪个页面
  4. 单词不要写错,否则报错不好找
  5. 知道每个功能的思路,更好的帮助我们理清
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值