django企业开发实战-学习小结

news2024/12/22 18:25:31

写在前面

初次阅读此书是三年前,当时没经历过完整的项目 觉得这书就是扯淡 后来经历过项目加班与毒打 今天再翻开此书 觉得实乃不可多得之物 花些时间啃下来吧

需求

需求文档

写文档,列举需要实现的功能,详细列举,不考虑技术实现细节

需求评审与分析

主要是将需求文档落实到技术细节,评审需求需要的技术栈,然后评审需求是否可实现,预估每个子需求的工作量等

此处可以考虑后续的衍生需求,考虑技术实现是否可行是否困难,技术需要的工作量等

功能分析

技术人员对需求评审的结果进行技术实现分析,模块划分等

模块划分可以基于数据实体制作ER图,或者建立UML图

模块划分

作用是将一个大项目分成几个小模块,让手下的人去按模块开发

框架基础和技术选型

需要选择 语言 框架 数据库 然后考虑团队开发与实现能力等

wsgi

wsgi,全称Web Server Gateway Interface,Web服务器网关接口,是用来规定web server应如何和程序交互的网关协议。可以理解为一个web应用的容器,适配了程序和操作系统之间功能,将操作系统一些功能抽象为接口提供给程序使用

可以使用wsgi,目的是使用实现统一协议的web server,不然换着乱

简单的web server

一个基本的socket监听程序

# coding:utf-8

import socket

EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = 'hello, world<h1> from tjh </h1>'
resp_params = [
    'HTTP/1.0 200 OK',
    'Date: Sun, 31 jul 2024 09:35:33 GMT',
    'Content-Type: text/html; charset=utf-8',
    'Content-Length: ()\r\n'.format(len(body.encode())),
    body
]

resp = '\r\n'.join(resp_params)

def handle_connection(conn, addr):
    req = b''
    while EOL1 not in req and EOL2 not in req:
        req += conn.recv(1024)
    print(req)
    conn.send(resp.encode())
    conn.close()
    
def main():
    ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ss.bind(('127.0.0.1', 8000))
    ss.listen(5)  # conn max queue number
    print('http://127.0.0.1:8000')
    
    try:
        while True:
            conn, addr = ss.accept()
            handle_connection(conn, addr)
    finally:
        ss.close()
        
if __name__ == '__main__':
    main()

效果

注意 Content-Type为text/plain 还是text/html

多线程版web server

还是阻塞模式,非阻塞会报错 还没处理

# coding:utf-8

import socket
import errno
import threading
import time

EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = 'hello, world<h1> from tjh </h1>-from {thread_name}'
resp_params = [
    'HTTP/1.0 200 OK',
    'Date: Sun, 31 jul 2024 09:35:33 GMT',
    'Content-Type: text/html; charset=utf-8',
    'Content-Length: {length}\r\n',
    body
]

resp = '\r\n'.join(resp_params)

def handle_connection(conn, addr):
    req = b''
    while EOL1 not in req and EOL2 not in req:
        req += conn.recv(1024)
    print(req)
    current_thread = threading.currentThread()
    content_length = len(body.format(thread_name=current_thread.name).encode())
    print(current_thread.name)
    conn.send(resp.format(thread_name=current_thread.name, length=content_length).encode())
    conn.close()
    
def main():
    ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # ss.setblocking(0)  # set socket mode as non block 
    # ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ss.bind(('127.0.0.1', 8000))
    ss.listen(10)  # conn max queue number
    print('http://127.0.0.1:8000')
    # ss.setblocking(0)  # set socket mode as non block 
    
    try:
        i = 0
        while True:
            try:
                conn, addr = ss.accept()
            except socket.error as e:
                if e.args[0] != errno.EAGAIN:
                    raise
                continue
            i += 1
            print(i)
            t = threading.Thread(target=handle_connection, args=(conn, addr), name='thread-%s' % i)
            t.start()
    finally:
        ss.close()
        
if __name__ == '__main__':
    main()

效果

简单wsgi application

wsgi协议分为两部分,一个是web server,一个是web application。接受请求时,会通过wsgi协议将数据发给web application,application处理完后,设置对应状体和header,之后返回body给web server,web server拿到数据后,进行http协议封装,返回完整http response

# coding: utf-8

import os
import sys

from app import simple_app

def wsgi_to_bytes(s):
    return s.encode()

def run_with_cgi(app):
    environ = dict(os.environ.items())
    environ['wsgi.input'] = sys.stdin.buffer
    environ['wsgi.errors'] = sys.stderr
    environ['wsgi.version'] = (1, 0)
    environ['wsgi.multithread'] = False
    environ['wsgi.multiprocess'] = True
    environ['wsgi.run_once'] = True
    
    if environ.get('HTTPS', 'off') in ('on', '1'):
        environ['wsgi.url_scheme'] = 'https'
    else:
        environ['wsgi.url_scheme'] = 'http'
        
    headers_set = []
    headers_sent = []
    
    def write(data):
        out = sys.stdout.buffer
        if not headers_set:
            raise AssertionError('write() before start_response()')
        elif not headers_sent:
            status, resp_headers = headers_sent[:] = headers_set
            out.write(wsgi_to_bytes('Status: %s\r\n' % status))
            for header in resp_headers:
                out.write(wsgi_to_bytes('%s: %s\r\n' % header))
            out.write(wsgi_to_bytes('\r\n'))
        out.write(data)
        out.flush()
        
    def start_response(status, resp_headers, exc_info=None):
        if exc_info:
            try:
                if headers_sent:
                    raise (exc_info[0], exc_info[1], exc_info[2])
            finally:
                exc_info = None
        elif headers_set:
            raise AssertionError('headers already set')
        
        headers_set[:] = [status, resp_headers]
        return write
    
    result = app(environ, start_response)
    try:
        for data in result:
            if data:
                write(data)
        if not headers_sent:
            write('')
    finally:
        if hasattr(result, 'close'):
            result.close()
            
if __name__ == '__main__':
    run_with_cgi(simple_app)

理解wsgi

wsgi规定,application必须是一个可调用对象,则这个可调用对象可以是函数或实现了__call__方法的实例

wsgi中间件和werkzeug

flask 

截至目前 有了两种方法提供web服务:直接通过socket处理请求,或者通过实现wsgi application部分协议

入门推荐

py微型框架有比如web.py, bottle,flask等 flask是一个不错的微型框架

tornado

高性能。tornado不是基于wsgi协议的框架,但提供了wsgi的支持,特性是异步和非阻塞。可以使用自带的http server进行部署而不是wsgi,因为wsgi是一个同步接口

和flask相比,tornado更侧重性能,整体并不比flask丰富,flask更多的支持对业务的满足

django

和微型框架不同,django框架不是仅需要两三个py文件就能跑起来的web框架,django功能更全也更大

django起步

管理系统后台开发

先安装django,再django-admin startproject project_name创建初始项目

cd到project下,创建一个app

models.py

from django.db import models

# Create your models here.
class Student(models.Model):
    SEX_ITEMS = [(1, '男'), (2, '女'), (0, '未知')]
    STATUS_ITEMS = [(0, '申请'), (1, '通过'), (2, '拒绝')]
    
    name = models.CharField(max_length=128, verbose_name='姓名')
    sex = models.IntegerField(choices=SEX_ITEMS, verbose_name='性别')
    profession = models.CharField(max_length=128, verbose_name='职业')
    email = models.EmailField(verbose_name='Email')
    qq = models.CharField(max_length=128, verbose_name='QQ')
    phone = models.CharField(max_length=128, verbose_name='电话')
    
    status = models.IntegerField(choices=STATUS_ITEMS, default=0, verbose_name='审核状态')
    created_time = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='创建时间')
    
    def __str__(self):
        return '<Student: {}>'.format(self.name)
    
    class Meta:
        verbose_name = verbose_name_plural = '学员信息'

admin.py

from django.contrib import admin

# Register your models here.
from .models import Student


class StudentAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'sex', 'profession', 'email', 'qq', 'phone', 'status', 'created_time')
    list_filter = ('sex', 'status', 'created_time')
    search_fields = ('name', 'profession')
    fieldsets = (
        (None, {
            'fields': (
                'name',
                ('sex', 'profession'),
                ('email', 'qq', 'phone'),
                'status'
            )
        })
    )


admin.register(Student, StudentAdmin)

将创建的app在setting中加到installed_apps下

创建数据库迁移文件 python manage.py makemigrations

创建表 python manage.py migrate

创建超级用户 python manage.py createsuperuser

运行测试服务器,访问127.0.0.1:8000 发现是默认页面

访问127.0.0.1:8000/admin会跳转到刚开发的管理员页面,然后用刚创的管理员用户名和密码登录

管理员页面语言是英文,时区也是UTC,可在setting进行配置

重新启动测试服务器,再次登入管理员页面,发现语言变成中文

管理系统前台开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode Hot 100刷题记录 -Day6(滑动窗口)

无重复字符的最长子串 问题描述&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s …

10:Logic软件原理图中添加电源与GND

Logic软件原理图中添加电源与GND

“品牌VS套路:华为、格行、中兴随身WiFi谁才是真良心?“

咱们打工人月末有三光&#xff0c;工资花光&#xff0c;流量用光&#xff0c;话费剩光光。 不过除了工资没办法解决&#xff0c;剩下两个还能抢救一下 提起这个事情的起因是我发现现在的互联网平台到处都是推销随身WiFi的&#xff0c;什么零月租、几百G流量不限速不限量啥的&…

Cortex-A7支持的内存类型详解及配置举例

0 参考资料 Introduction to memory protection unit management on STM32 MCUs.pdf ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf 1 Cortex-A7支持的内存类型详解 1.1 内存类型 ARM架构处理器支持的内存类型分为三种&#xff0c;分别是Normal memory&…

airflow看不到任务日志解决方案

1. 基础信息 airflow 版本&#xff1a;2.5.3 2. 问题现象 airflow web-server 界面&#xff0c;看到某些任务的具体运行日志&#xff0c;只有少量日志&#xff0c;如下图所示&#xff1a; 具体日志内容如下&#xff1a; na-fudao-data-airflow-test-2-21.alibji.zybang.com…

某视频云平台存在未授权窃取用户凭据漏洞

我和你一样&#xff0c;历经破碎、痛苦的生活&#xff0c;却未垮掉&#xff0c;每一日都从承受的苦难中&#xff0c;再一次将额头浸入光明 漏洞详情&#xff1a; 某视频云平台存在未授权访问漏洞&#xff0c;攻击者可以直接访问平台的API接口文档&#xff0c;从而获取系统的A…

【大模型】Reflextion解读

前言&#xff1a;一种大模型强化学习技术&#xff0c;将传统的梯度更新时的参数信号替换成上下文的语言总结&#xff0c;过程和人类反思相似。区别与RLHF&#xff0c;Reflextion是agent自我反思&#xff0c;RLHF是人类反馈。 目录 1. 基础知识1.1 强化学习1.2 大模型Agent 2. 创…

Upload-LABS通关攻略【1-20关】

Pass-01 第一关是前端JS绕过 上传一个php文件显示只能上传特定后缀名的文件 这里将1.php改为1.jpg直接进行抓包&#xff0c;在数据包中将jpg改为php放行 文件上传成功&#xff0c;邮件图片新建页面打开 可以访问到1.php文件&#xff0c;则一句话密码上传成功 使用蚁剑 进行连接…

探秘DevSecOps黄金管道,安全与效率的完美融合

软件应用的安全性已成为企业和用户关注的焦点&#xff0c;DevSecOps作为一种将安全融入开发和运维全过程的理念和实践&#xff0c;旨在消除传统开发模式中安全被后置处理的弊端。DevSecOps黄金管道&#xff08;Golden Pipeline&#xff09;是实现这一理念的核心框架&#xff0c…

蜂鸣器奏乐

一、粗略了解简谱 拍号&#xff1a;如图&#xff0c;“2”表示一个小节有2拍&#xff0c;“4”表示4分音符为一拍 终止线表示歌曲结束 注意&#xff1a;以下音符都按以四分音符为一拍计算拍数 四分音符&#xff1a; 唱一拍 二分音符&#xff1a; 某一个音右边有一个小横线&…

OpenAI GPT3 Search API not working locally

题意&#xff1a;"OpenAI GPT-3 搜索 API 在本地无法工作" 问题背景&#xff1a; I am using the python client for GPT 3 search model on my own Jsonlines files. When I run the code on Google Colab Notebook for test purposes, it works fine and returns …

文件上传漏洞详解(持续更新…)

第一关 步骤一&#xff0c;打开第一关先点击浏览上传一个jpg格式的图片 步骤二&#xff0c;打开BP修改jpg为php然后放包 步骤三&#xff0c;右键打开图像 成功解析 步骤四&#xff0c;打开蚁剑 第一关还是蛮简单的 第二关 步骤一&#xff0c;打开第二关先点击浏览上传一个j…

leetcode637. 二叉树的层平均值,广度优先搜索BFS

leetcode637. 二叉树的层平均值 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。…

跑通llama-factory

1.在ubuntu下安装环境 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e “.[torch,metrics]” pip install --no-deps -e . 在本地windows&#xff0c;打开http://0.0.0.0:7863/&#xff0c;总是显示无法打开界面。 之后在…

!!学习整理知识模块——关于【如何本地搭建Whisper语音识别模型】/请按需收藏!!

成长路上不孤单&#x1f60a;【14后&#xff0c;C爱好者&#xff0c;持续分享所学&#xff0c;如有需要欢迎收藏转发&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#xff01;&#xff01;&#xff01;&#xff01;&#xff…

经验风险最小化和极大似然估计的关系

一、经验风险定义 给定一个训练数据集 T { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} T{(x1​,y1​),(x2​,y2​),...,(xN​,yN​)}&#xff0c;模型f(X)关于训练数据集的平均损失称为经验风险&#xff08;Empirical…

冻死你都觉得简单

小说大纲 标题&#xff1a;《学霸的豪门对决》 背景设定&#xff1a; 两个家族在商业界拥有举足轻重的地位&#xff0c;但因为历史原因&#xff0c;两家长期处于竞争状态。主角们在顶级私立学校就读&#xff0c;既是学霸也是家族的继承人。 主要人物&#xff1a; 男主角&a…

【前端开发必备小技巧】前端代码规范Vue篇

文章目录 &#x1f7e2; 前端代码规范&#x1f7e2; 一、前端代码规范Vue篇&#x1f449;1、Vue编码基础&#x1f449;1.1、组件规范&#x1f449;1.2、模板中使用简单的表达式&#x1f449;1.3、指令都使用缩写形式&#x1f449;1.4、 标签顺序保持一致&#x1f449;1.5、必须…

<数据集>车辆识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;3002张 标注数量(xml文件个数)&#xff1a;3002 标注数量(txt文件个数)&#xff1a;3002 标注类别数&#xff1a;21 标注类别名称&#xff1a;[ambulance, army vehicle, auto rickshaw, bicycle, bus, car, garba…

互联网平台大模型网络架构设计

字节跳动&#xff1a;大模型网络实践分享 自2019年起&#xff0c;字节跳动公司便开始着手白盒项目。2020年&#xff0c;推出了首款接入交换机——25G型号&#xff0c;随后逐步实现软硬件的自主研发。在当前一代产品中&#xff0c;已经实现了100G接入、25.6T400G互联&#xff0c…