Django从入门到学会——03

本文详细介绍了如何配置数据库、创建Django应用并实现增删改查功能,涵盖了视图函数、模板设计及数据库操作。此外,还涉及了SQL查询技巧、HTTP协议应用、文件上传和会话管理。

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

一、博客案例

1.配置准备

#配置模板文件夹
'DIRS': [os.path.join(BASE_DIR,'templates')],
    
#导入数据库
import pymysql
pymysql.install_as_MySQLdb()
    
# 数据库配置文件准备
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myblog9_10',
        'USER':'admin',
        'PASSWORD':'qwe123',
        'HOST':'127.0.0.1',
        'POST':3306
    }
}
#创建app,并分配路由

2.代码展示

  • 首先要构建一个网站的大致思路
    1. 模板HTML文件
    2. 添加页面,列表页面,详情页面,索引页面
    3. 创建模型类和数据库,并存入类型。
    4. 接下来就是边写视图函数,边写跳转的页面
1.视图函数
from django.shortcuts import render,redirect,reverse
from django.http import HttpResponse
# Create your views here.
from .models import BlogModel


def index(request):
    return render(request,'blog/demo_index.html')


def blog_add(request):
    #访问页面
    if request.method=='GET':
        return render(request,'blog/demo_add.html')
    # 如果是页面添加的的数据,则要得到
    elif request.method=='POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        blog = BlogModel(title=title,content=content)
        blog.save()
        b_list = BlogModel.objects.all()
        return render(request,'blog/demo_list.html',context={'b_list':b_list})

def blog_show(request):
    b_list = BlogModel.objects.all()
    return render(request, 'blog/demo_list.html', context={'b_list': b_list})


def blog_detail(request,blog_id):
    blog = BlogModel.objects.get(id = blog_id)
    return render(request,'blog/demo_detail.html',context={'blog':blog})


def blog_delete(request,blog_id):
    blog = BlogModel.objects.filter(id=blog_id)
    # 在这里不能用get
    if blog:
        blog.delete()
        return redirect(reverse('list'))    #重定向,无法确定是哪一个过来的
    else:
        return HttpResponse('无法删除')
def blog_update(request,blog_id):
    blog = BlogModel.objects.filter(id=blog_id)

    if request.method=='GET':
        return render(request,'blog/demo_update.html',context={'blog':blog})
    elif request.method=='POST':
        title = request.POST.get('title')
        content = request.POST.get('content')
        BlogModel.objects.filter(id = blog_id).update(title=title,content=content)
        return redirect(reverse('update'))
2. demo_base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}
    模板文件
    {% endblock %}</title>
</head>
<body>
{% block body %}


{% endblock %}
</body>
</html>
3.demo_add.html
{% extends 'blog/demo_base.html' %}

{% block title %}
添加博客
{% endblock %}

{% block body %}

{#    防止跨域请求#}
    <form action="{% url 'add' %}" method="post"> {% csrf_token %}
        标题 <input type="text" id="title" name="title" placeholder="请输入文章标题"> <br>
        内容 <textarea name="content" id="content" cols="30" rows="10" placeholder="请输入文章"></textarea> <br>
    <button type="submit">发布文章</button>
    <button type="reset">重置</button>
    </form>
    <br>
    <a href="{% url 'index' %}">返回首页</a>
{% endblock %}
4.demo_detail.html
{% extends 'blog/demo_base.html' %}

{% block title %}
文章详情
{% endblock %}

{% block body %}
    <h1>{{ blog.title }}</h1>
    <p>{{ blog.content }}</p>
    <br>
    <a href="{% url 'list' %}">返回列表页</a>
{% endblock %}
5.demo_index.html
{% extends 'blog/demo_base.html' %}

{% block title %}
博客首页
{% endblock %}

{% block body %}
<p><a href="{% url 'add' %}">添加博客</a></p>
<p><a href="{% url 'list' %}">博客列表</a></p>
{% endblock %}
6.demo_list.html
{% extends 'blog/demo_base.html' %}

{% block title %}
博客列表
{% endblock %}

{% block body %}
<h1>文章列表</h1>
<table>
        <tr>
            <th>标题</th>
            <th>操作</th>
        </tr>
    {% for b in b_list %}

    <tr>
        <td><a href="{% url 'detail' b.id %}">{{ b.title }}</a></td>
        <td><a href="">编辑</a>&emsp;<a href="{% url 'delete' b.id %}">删除</a></td>
    </tr>
    {% endfor %}
</table>

    <a href="{% url 'index' %}">返回首页</a>
{% endblock %}
7.demo_update.html
{% extends 'blog/demo_base.html' %}

{% block title %}
修改博客
{% endblock %}

{% block body %}

{#    防止跨域请求#}
    <form action="{% url 'update' blog.id %}" method="post"> {% csrf_token %}
        标题 <input type="text" id="title" name="title" value="{{ blog.title }}"> <br>
        内容 <textarea name="content" id="content" cols="30" rows="10">{{ blog.content }}</textarea> <br>
    <button type="submit">修改文章</button>
    </form>
    <br>
    <a href="{% url 'list' %}">返回列表页</a>
{% endblock %}

二、查询补充

from django.db.models import Count,Max,Min,Q,F,Avg,Sumdef model_info(request):    # 聚合查询    res = Stu_datail.objects.all().aggregate(Avg('age'))    #分组查询,根据学院ID,统计每个学院有多少个学生    res = Student.objects.values('dept_id').annotate(Count('dept_id'))    #F查询,查询学号和学院ID号相等的数据    res = Student.objects.filter(s_id=F('dept_id'))    Stu_datail.objects.all().update(age=F('age')+1)    #Q查询 & | ~——与或取反    res = Student.objects.filter(Q(s_name='小黄') & Q(s_id=5))    res = Student.objects.filter(Q(s_name='小黄') | Q(s_id=5))    res = Student.objects.filter(Q(s_name='小黄') & ~Q(s_id=5))    print(res)    return HttpResponse("数据查询成功")

三、请求与响应

1.request的对象内容

def index(request):    print(request) #对象    print(request.path) #请求的路由    print(request.method)    print(request.encoding)    print(request.get_host()) #IP和端口    print(request.get_port()) #端口    return render(request,'get_post/index.html')
  • 一般渲染页面用get方式,提交数据用post方式

  • 用request.post.getlist()——获取多选的内容。

  • # 类视图函数——可以区分post和getfrom django.views import Viewclass Blog_update(View):    def get(self):        pass    def post(self):        pass#路由#views.Blog_update.as_view()
    

2.文件上传:

  • 存储文件一般都不会存储在数据库中,而是存一个链接

settings文件配置

STATIC_URL = '/static/'STATICFILES_DIRS=[    os.path.join(BASE_DIR,'static')]MEDIA_ROOT=os.path.join(BASE_DIR,'static/media')
  • 上传音频
from django.views import Viewimport osfrom myblog9_10.settings import MEDIA_ROOTclass Upload(View):    def get(self,request):        return render(request,'get_post/index.html')    def post(self,request):        f = request.FILES.get('file') #获取文件名        f_name=os.path.join(MEDIA_ROOT,f.name)  #拼接文件名        with open(f_name,'wb+') as fp:            for i in f.chunks(): #读取文件的内容                fp.write(i)        return HttpResponse('当前文件上传完毕')

3.HTTP协议

可以返回一个json格式的数据。return JsonResponse({‘一个’:‘两盒’})——严格的键值对的形式。

客户端和服务器记录登陆状态、

4.cookie

import datetime# 设置cookiedef set_ck(request):    response = HttpResponse('设置cookie')    # response.set_cookie('name','anyan') # 浏览器就过期。    # response.set_cookie('name','anyan',max_age=5) # 浏览器打开5秒后就过期。    response.set_cookie('name','anyan',expires=datetime.datetime(2021,10,1)) #指定过期时间    return response    #获取cookiedef get_ck(request):    ck = request.COOKIES    name = ck.get('name')    return HttpResponse(name)# 删除cookiedef dele_ck(request):    response = HttpResponse('删除cookie')    response.delete_cookie('name')    return response

5. session状态表单

  • session存在服务器当中,cookie存在于客户端中。
# Create your views here.def home(request):    username = request.session.get('username','用户未登录')    if username=='用户未登录':        return redirect(reverse('login'))    return render(request,'form_session/home.html',context={'username':username})class Lodin(View):    def get(self,request):        return render(request,'form_session/login.html')    def post(self,request):        username = request.POST.get('user')        request.session['username'] = username        request.session.set_expiry(0)#0表示关闭页面就过期        return redirect(reverse('home'))def logout(request):    request.session.flush()    return redirect(reverse('home'))

6.生成表单

forms.py

from django import formsclass RegisterForm(forms.Form):    username = forms.CharField(max_length=30,min_length=4)    password = forms.CharField(max_length=16,min_length=6,widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}))    password_confirm = forms.CharField(max_length=16,min_length=6,widget=forms.PasswordInput(attrs={'placeholder':'请再次输入密码'}))    email = forms.EmailField()

视图函数

from .forms import RegisterFormfrom .models import *def logout(request):    request.session.flush()    return redirect(reverse('home'))class RegisterTest(View):    def get(self,requset):        form = RegisterForm()        return render(requset,'form_session/register.html',context={'form':form})    def post(self,request):        form = RegisterForm(request.POST) #获取表单数据        if form.is_valid(): #判断数据是否合法            username = form.cleaned_data.get('username')    # 保存数据            pwd = form.cleaned_data.get('password')    # 保存数据            pwd_confirm = form.cleaned_data.get('password_confirm')    # 保存数据            email = form.cleaned_data.get('email')    # 保存数据            if pwd==pwd_confirm:                Usermodel.objects.create(username=username)            else:                return HttpResponse('用户注册失败')        else:            return HttpResponse('数据不合法')

四、中间件

创建中间件函数文件,并将文件添加到配置文件中的MIDDLEWARE

settings文件

MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    'myblog9_10.mymiddleware.MyException']

在中间件的地方加入直接返回视图的话,就到不了视图函数。

mymiddleware文件

from django.http import HttpResponsefrom django.utils.deprecation import MiddlewareMixin# 用已经定义好了的方式来改写class MyException(MiddlewareMixin):    def process_request(self,request):        print('中间件被调用')        request.name = 'anyan'        return None        # return HttpResponse(111)# 用自身的魔法方法来修改class UserMiddleware(MiddlewareMixin):    def __init__(self,get_response):        self.get_response = get_response    def __call__(self,request):        #请求到达视图函数之前        username = request.session.get('username','用户未登录')        if username!='用户未登录':            setattr(request,'myuser',username)        else:            setattr(request,'myuser','用户未登录')        print('==============request===========')        response = self.get_response(request)        print('==========response==========')        return response

五、上下文处理器

创建上下文函数文件,并将文件添加到配置文件中的TEMPLATES

settings文件

TEMPLATES = [    {        'BACKEND': 'django.template.backends.django.DjangoTemplates',        'DIRS': [os.path.join(BASE_DIR,'templates')],        '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',                'myblog9_10.mycontext.my_user',            ],        },    },]

mycontext 文件

#可以在项目中的所有位置使用myuser这个属性def my_user(request):    user = request.session.get('username','用户未登录')    if user !='用户未登录':        return {'myuser':user}    else:        return {'myuser':'用户未登录,请先登录!'}

1.admin

  • 创建超级用户管理员——在run manage.py中运行,createsuperuser,
  • 界面在admin视图函数中

管理界面中文显示——settings文件中

LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = 'Asia/Shanghai'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = False

在管理后台的表中添加app中的其他表,要在app下的admin.py中修改数据如下

models.py文件

from django.db import models# Create your models here.class Usermodel(models.Model):    username = models.CharField(max_length=20)#学院信息表class Department(models.Model):    d_id = models.AutoField(primary_key=True)    d_name = models.CharField(max_length=30,unique=True)    def __str__(self):        return f'd_id={self.d_id},d_name={self.d_name}'#学生表格class Student(models.Model):    s_id = models.AutoField(primary_key=True)    s_name = models.CharField(max_length=30)    dept_id=models.ForeignKey('Department',on_delete=models.SET_NULL,null=True)    def __str__(self):        return f's_id={self.s_id},s_name={self.s_name},dept_id={self.dept_id}'#学生详情表class Stu_datail(models.Model):    sd_id  =models.AutoField(primary_key=True)    age = models.IntegerField()    sex = models.BooleanField(default=True)    intro = models.TextField(null=True)    s_id = models.OneToOneField('Student',on_delete=models.CASCADE)    def __str__(self):        return f'sd_id={self.sd_id},sd_name={self.sd_name},age={self.age},sex={self.sex},intro={self.intro}'# 学生课程表class Course(models.Model):    c_id = models.AutoField(primary_key=True)    c_name = models.CharField(max_length=30,unique=True)    stu_course = models.ManyToManyField('Student')    def __str__(self):        return f'c_id={self.c_id},c_name={self.c_name}'

admin.py文件

from django.contrib import admin# Register your models here.from .models import Student,Usermodel,Stu_datail,Course,Departmentclass StudentAdmin(admin.ModelAdmin):    list_display = ['s_id','s_name'] #显示字符,只显示名字和id,但是要注册进去    list_filter = ['s_id']  #设置过滤字段    search_fields = ['s_id'] #设置搜索字段    list_per_page = 2 #分页,一页两条数据class StuDetailAdmin(admin.ModelAdmin):    fields = ['age','intro']    #属性显示的先后顺序,决定你要显示几个字段    #属性分组,与上面的显示方式二选一    fieldsets = [        ('第一列',{'fields':['age']}),        ('第一列',{'fields':['intro','sex']}),    ]#将表注册进后台管理中admin.site.register(Usermodel)admin.site.register(Stu_datail,StuDetailAdmin)admin.site.register(Student,StudentAdmin)admin.site.register(Course)admin.site.register(Department)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Indra_ran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值