Django数据库关联表、页面模板和jinja2前端模板引擎相关语法

Django关联数据库

  1. 关联

    • 1:1 OneToOneField 主键和外键是一对一的关系,在关联表中,只能关联一个主表的id
      • 拓展表找主表: 拓展信息对象.关联字段
      • 主表找拓展表: 主表对象.关联表的model_name
    • 1: N
    • M :N
  2. on_delete

    • 默认cascade, 主表删除, 从表也删除
    • set_null 主表删除, 从表关联字段设为空
    • protect 不让删除
    • set_default, 主表删除,从表关联字段设置为默认值

一对一

  • models.py文件中
class Student(models.Model):
    stu_name = models.CharField(max_length=10)
    stu_sex = models.BooleanField()
    stu_birth = models.DateField()
    stu_create_time = models.DateTimeField(auto_now_add=True)
    stu_operate_time = models.DateTimeField(auto_now=True)
    stu_yuwen = models.DecimalField(max_digits=3, decimal_places=1)
    stu_math = models.DecimalField(max_digits=3, decimal_places=1)
    g = models.ForeignKey(Grade, null=True)

    class Meta:
        db_table = 'stu'


class StudentInfo(models.Model):

    stu_addr = models.CharField(max_length=30)
    stu_age = models.IntegerField()
    # 这个字段和学生表的ID关联起来相当于外键,related_name可以让主表找到拓展表
    stu = models.OneToOneField(Student, on_delete=models.CASCADE, related_name='stu_info')

    class Meta:
        db_table = 'stu_info'

- views.py文件中
def addStu(request):
    if request.method == 'GET':
        return render(request, 'addstu.html')
    if request.method == 'POST':
        stu_name = request.POST.get('name')
        if request.POST.get('sex') == '男':
            stu_sex = 1
        else:
            stu_sex = 0
        stu_birth = request.POST.get('birth')
        stu_yuwen = request.POST.get('yuwen')
        stu_math = request.POST.get('math')

        Student.objects.create(
            stu_name=stu_name,
            stu_sex=stu_sex,
            stu_birth=stu_birth,
            stu_yuwen=stu_yuwen,
            stu_math=stu_math
        )
        return render(request, 'addstu.html')


def selStu(request):

    # 通过扩展表学生的地址去查学生的信息
    # 查找addr = 成都天府新区的学习信息

    # stus = StudentInfo.objects.filter(stu_addr='成都天府新区110号')
    # stu = stus[0]
    # selstu = Student.objects.filter(id=stu.stu_id)

    # 拓展表找主表: 拓展信息对象.关联字段
    # stus = StudentInfo.objects.filter(stu_addr__contains='天府新区')
    # stu = stus[0]
    # 中间的点stu是找到与Student表中对应的数据
    # stu = models.OneToOneField(Student, on_delete=models.CASCADE)
    # selstu = stu.stu

    # 通过学生表去查询学生拓展表的信息
    # 查询stu_name=刘备的学生的家庭住址
    # 方法1
    """
    select * from studentinfo s1 join
    (select id from student where stu_name='刘备') t1
    on s1.stu_id = t1.id
    """
    # stu = Student.objects.filter(stu_name='刘备').first()
    # selstu = StudentInfo.objects.filter(stu_id=stu.id)

    # 方法2
    stu = Student.objects.filter(stu_name='刘备').first()
    # 下面方法只可以用一种,如果用model_name,就不能设置关联名
    # 注意model_name 要全小写
    # selstu = stu.studentinfo
    selstu = stu.stu_info

    return render(request, 'selstu.html', {'selstu' : selstu})

一对多

  • models.py文件中
  • student数据与上面的一样就不一一列出
class Grade(models.Model):
    g_name = models.CharField(max_length=10)

    class Meta:
        db_table = 'grade'
def fselStu(request):

    # 查询python班级下的学生信息
    # 方法1
    # g = Grade.objects.get(g_name='python')
    # stus = Student.objects.filter(g_id=g.id)
    # 方法2
    # g = Grade.objects.get(g_name='python')
    # stus = g.student_set.all()

    # 查询叫李白的同学的班级信息
    # stu = Student.objects.get(stu_name='刘备')
    # gs = stu.g

    # 查询python班下语文成绩大于80分的学生
    # g = Grade.objects.get(g_name='python')
    # stus = g.student_set.filter(stu_yuwen__gte=80)

    # 查询python班级中出生在80后的男生的信息
    # g = Grade.objects.get(g_name='pyhon')
    # g.student_set.filter(stu_birth__gte='1980-01-01',
    #                      stu_birth_lt='1990-01-01',
    #                      stu_sex=True)
    # 查询python班级下语文成绩超过数学成绩10分的男同学信息
    g = Grade.objects.get(g_name='python')
    stus = g.student_set.filter(stu_yuwen__gte=F('stu_math') + 10,
                         stu_sex=True)

    return render(request, 'selgrade.html',{'stus': stus})

多对多

  • models.py文件中
  • 在迁移到数据库时,会自动生成一个关联两个表的关联表
class GoodsUser(models.Model):
    u_name = models.CharField(max_length=10)

    class Meta:
        db_table = 'good_user'


class Goods(models.Model):
    g_name = models.CharField(max_length=10)
    g_user = models.ManyToManyField(GoodsUser)

    class Meta:
        db_table = 'goods'
  • views.py文件中的内容
def manyGoods(request):

    # 获取小乔购买的商品
    u = GoodsUser.objects.filter(u_name='小乔')[0]
    goods = u.goods_set.all()


    # 获取购买哇哈哈客户的信息
    g = Goods.objects.get(g_name='哇哈哈')
    users = g.g_user.all()

    return render(request, 'goods.html', {'goods' : goods, 'users': users})

小技巧 python manage.py makemigrations appname 强制执行

static

  • 放css/js/images等文件
  • 在主目录下创建static文件夹
  • 在settings.py文件中修改如下代码
  • 静态资源加载
    • static/images/xxx.png
    • {% load static %}
    • {% static ‘images/xx.png’ %}
STATIC_URL = '/static/'
# 新增,为了让系统可以找static文件夹下的内容
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

jinja2 前端模板引擎

挖坑、填坑

挖坑

  • 做成一个模板,方便有重复的页面可以调用
  • 在{% %}中的数据可以在其他页面添加,是可以变得
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>

        {% block title %} {% endblock %}
    </title>
</head>
<body>
    <h5>呵呵</h5>
    {% block contain %} {% endblock %}
</body>
</html>

填坑

  • 补全之前有坑的地方,文章的结构不会改变
  • 要用extends方法继承之前的模板页面,include方法不会将之前的页面结构导入进来

{#{% include 'base.html' %}#}
{% extends 'base.html' %}
{% block title %}
    我是标题
{% endblock %}
{% block contain %}
    我是内容
{% endblock %}
  • 在页面中一些常用的语法
"""
1.for
 {% for i in stu %}
{% empty %}
{% endfor %}

2.if
{% if xxx %}
{% endif %}

3. ifequal
{% ifequal xxx 1 %}
{% else %}
{% endifequal %}

4. forloop
forloop.counter
计数从0开始:{{ forloop.counter0 }} 
计数从1开始:{{ forloop.counter }}
计数从最后开始,到1停:{{ forloop.revcounter }} 
计数从最后开始,到0停:{{ forloop.revcounter0 }} 

5. 过滤器 (|)
在变量显示前修改
add 加法,增加值
"""

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for stu in stus %}
    计数从0开始{{ forloop.counter0 }}&nbsp;&nbsp;
    计数从1开始{{ forloop.counter }}&nbsp;&nbsp;
    计数从最后开始到1结束{{ forloop.revcounter }}&nbsp;&nbsp;
    计数从最后开始到0结束{{ forloop.revcounter0 }}&nbsp;&nbsp;
    {% ifequal forloop.counter 3 %} # 当forloop.counter等于3时
       <h1>姓名:{{ stu.stu_name }}</h1>
    {% else %}
        姓名:{{ stu.stu_name }}
    {% endifequal %}
    性别:
    {% if stu.stu.sex %}
        男
    {% else %}
        女
    {% endif %}
    &nbsp;&nbsp;&nbsp;
    生日:{{ stu.stu_birth }}
    创建时间:{{ stu.stu_create_time }}
    语文成绩:{{ stu.stu_yuwen | add:10 }}输出时加了10分
    数学成绩:{{ stu.stu_math | add:-10}}输出时减了10分
    <br />
{% empty %}
    没有学生信息
{% endfor %}
</body>
</html>

扩展

  • get: www.baidu.com?s=python&j=java

    • ?后面跟参数,&来连接参数
  • exclude: 查询不满足条件的所有信息

  • banner 页面中的滚动图片

  • crm 后台

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值