Django-图片服务器-流程梳理

Django
正所谓技术是实践经验的积累,在学习了python爬虫、mysql的相关知识后,手痒难耐,心中豪气迸发,想做一个自己的网站,虽然咱目标就是当个互联网杂鱼,但是咋滴也得干一点点事情。说干就干,python的Django框架作为老牌的后端框架,呲呲呲,那咱还不是拿来主义,嘿嘿嘿。耗时一周这基于django框架的后端总算实现了咱初步的设想,下面来梳理一下流程。
按照步骤一步步复制操作即可建立一个简单的图片存储的后台。
这里安装的坑就不介绍,直接上代码了
第一步(创建项目及配置)
打开cmd窗口,转至创建项目的文件夹
文件夹目录下,创建工程:django-admin startproject project
创建应用:python manage.py startapp myapp
进入mysql:mysql -u root -p
mysql数据库下创建database:creat database pictures;

第二步(项目配置)
配置SQL数据库、激活应用、汉化,project下的setting.py下设置
数据库
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.mysql’,
‘NAME’: ‘pictures’,
‘USER’:‘root’,
‘PASSWORD’:‘root’,
‘HOST’:‘localhost’,
‘PORT’:‘3306’
}
}

激活项目
installed_APPS选项中加上一句:‘myapp’

汉化、设置时区
settings.py文件找到language_code 和time_zone
language_code = ‘zh-Hans’
time_zone= ‘Asia/Shanghai’

第三步 模型版块
编辑文件models.py:(可以套用):

class UploadImage(models.Model):
    imgName = models.CharField(max_length=256, default="", verbose_name="文件名")  # verbose_name 详细名称
    imgMd5 = models.CharField(max_length=128, verbose_name="MD5值")
    imgType = models.CharField(max_length=32, verbose_name="类型")
    imgSize = models.IntegerField(verbose_name="大小")
    imgPath = models.CharField(max_length=128, verbose_name="图片路径")
    imgCreated = models.CharField(max_length=64, default=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    imgUpdated = models.CharField(max_length=64, default=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

    def __str__(self):
        return "%s-%d-%s" % (self.imgName, self.imgSize, self.imgPath)

UploadImage模型,数据主要包含 文件名、MD5值、文件类型、文件大小、文件绝对路径、创建时间和更新时间

cmd进入项目文件输入命令:
生成迁移文件:python manage.py makemigrations
迁移:python manage.py migrate
(这个就是把你模型定义的表格进行mysql的执行)
第四步启动服务器
cmd项目文件目录下
创建服务器管理员:python manage.py createsuperuser
启动服务器:python manage.py runserver { ip}: {port}
本地管理站点:127.0.0.1:8000/admin
(浏览器输入127.0.0.1:8000/admin 就能见到你的Django管理员页面)

自定义myapp的admin界面(包含子属性页面设置),
编辑myapp/admin.py文件:


from django.contrib import admin
from .models import UploadImage
@admin.register(UploadImage)      #注册显示界面的数据库,并修饰
class UploadAdmin(admin.ModelAdmin):
    #列表页属性
    def size(self):
        a=self.imgSize
        if a<1024:
            b=str(a)+'字节'
            return b
        elif a>1024 and a<1024*1024:
            b = str(a//(1024)) + 'KB'
            return b
        elif a > 1024*1024 and a < 1024 * 1024*1024:
            b = str(a//(1024*1024)) + 'MB'
            return b
    size.short_description = "大小"

    list_display=['imgName','imgType',size,'imgPath', 'imgUpdated']
    list_filter =['imgType']
    list_per_page=5
    fields =['imgName','imgMd5','imgType','imgSize','imgPath','imgCreated', 'imgUpdated']
    # fieldsets =[('num',{'fields':['imgName','imgMd5','imgType','imgSize']}),
    #            ('base',{'fields':['imgPath']}),
    #            ('ues', {'fields': [ 'imgCreated', 'imgUpdated']})
    #             ]
    actions_on_top = False
    actions_on_bottom = True

第五步 编辑视图

views版块
(后端的主要逻辑集中的地方包含:站点页面显示、模型数据获取、传递模板数据、连接模板、数据的处理、保存等操作):

这里代码分解开来,先讲解函数功能。
作为开发的枢纽,实现以下功能
1.响应主页面的请求

def function (request)
     return HttpResponse("你真好")

2.响应次级页面的请求

def detail(rquest,num):
     return HttpResponse("detail-%s"%num)

3.通过模型请求数据库数据,传递给模板(后面创建html会用到)

from .models import UploadImage
def picture(request):
    pictureList= UploadImage.objects.all()
    return render(request,'01.html',{
     'pictures':pictureList})

4.定义处理请求的函数,返回图片在服务器的url,

#哈希计算图片的md5值,返回
def get_file_md5(file):
    md5_obj = hashlib.md5()
    for chunk in file.chunks():
        md5_obj.update(chunk)
    return md5_obj.hexdigest()


# 重命名并写入
def rename(file):
    times = '2020'#time.strftime('%Y%m%d%H%M%S')   #获取当地时间
    ran = os.path.splitext(file.name)[0]#random.randint(0, 1000)           #生成0-1000的随机数
    ext = os.path.splitext(file.name)[1]    #分离文件的名字和扩展名;取拓展名
    new_file = "{}{}{}".format(times, ran, ext)  #时间+随机数+拓展名生成新文件名
    path = os.path.join('./pictures', new_file).replace('\\', '/')#存储图片的路径为 static/images/新图片名
    read = open(path, 'wb+')                #读写方式打开新文件
    for chunk in file.chunks():
        read.write(chunk)                   #写入图片的分块处理的信息,就是写入图片,默认值为2.5M
    read.close()
    return path

#
def upload(request):
    if request.method == 'POST':           #以post请求,request包含的是一个类,
        base_url = "http://" + request.META["HTTP_HOST"] + "/"  #重新拼接request的服务器地址
        files = request.FILES   #请求中附带的图片信息
        if files:
            ret = {
     'code': SUCCESS_CODE, 'message': SUCCESS_MESSAGE, 'urls': []}   #上传提示信息:200+上传成功+urls
            for fileName in files:
                file = request.FILES.get(fileName)
                if file.size > 5 * 1024 * 1024:                                       #设置图片大小不超过5M
                    return JsonResponse({
     'code': FAILURE_CODE, 'message': SIZE_ERROR}) #返回失败信息
                md5 = get_file_md5(file)        #得到图片的md5值
                img_obj = models.UploadImage.objects.filter(imgMd5=md5)  #将模型中的imgMd5赋值为图片的md5值
                #若成功获得md5值
                if img_obj:
                    url = base_url + img_obj.first().imgPath       #生成url
                    info = {
     'name': file.name, 'url': url}         #info 存储文件名+url
                else:
                    path = rename(file)                            #否则重新生成路径
                    path2=base_url+'static'+path[1:]  #可直接访问的url,若设置为本机以外的服务器,需要更改
                   # url = path2                                   #url=服务器地址+重新生成的路径
                    create = models.UploadImage.objects.create(
                        imgName=os.path.basename(path),
                        imgMd5=md5,
                        imgType=os.path.splitext(file.name)[1],
                        imgSize=file.size,
                        imgPath=path2)

                    info = {
     'name': file.name, 'url': path2}        #info 存储文件名+url
                ret['urls'].append(info)                          #提示   信息的url 附加服务器上的图片地址
            return JsonResponse(ret)                              #返回提示成功信息
        else:
            return JsonResponse({
     'code': FAILURE_CODE, 'message': FAILURE_MESSAGE}) #返回提示失败信息 #返回提示失败信息

以上定义的函数,需将其与站点的url连接起来才能进行站点的访问
第六步 分配站点
设置分为两个部分
myapp下urls.py 设置对应url 调用方法
project下urls.py 访问myapp的uls

配置url:
修改project下的urls.py文件

from django.contrib import admin
from django.urls import path, re_path
from django.conf.urls import include,url
#该页面决定服务器可以访问的网址,且这些网址都是展示怎样的页面需要连接myapp下的urls
urlpatterns = [
    path('admin/', admin.site.urls),             #管理台
    re_path(r'^',include('myapp.urls')),         #主页,myapp的连接
]
在这里插入代码片

在myapp下创建urls.py文件

from django.urls import re_path
from myapp import views
from django.conf.urls import url
urlpatterns = [
    re_path(r'^$', views.upload),    #访问主页网址,该项目views.upload用于post请求处理数据,不能进行访问
    url(r'^(\d+)/$',views.detail),   #访问主页网址后面加数字,仅用于展示该用法
    url(r'^picture/$',views.upload) #访问主页网址后面加/picture,该项目为显示01.html文件内容
]
在这里插入代码片

第七步 模板的使用(html文件的创建):
myapp下创建templates目录
配置模板路径:修改settings.py下的templates,加上
'DIRS':[os.path.join(BASE_DIR,'templates')] #根目录下的templates文件夹

由于是图片服务器,为了方便请求服务器获得图片数据在settings.py最后需要设置django自带的static方法

    #当连接中含有static时,django会在各个app的static文件夹寻找 static/后面的字段的文件
    STATIC_URL = '/static/'
    #当djanggo在app下找不到对应的文件,django在staticfiles_dirs指定的文件目录下寻找
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'pictures'),  #BASE_DIR 是文件根目录,指定文件根目录下的pictures文件夹
        os.path.join(BASE_DIR),
    #BASE_DIR是项目跟目录
    ]

设置完毕后 请求http://127.0.0.1:8000/static/pictures即可获得相应的图片,

请求1: http://127.0.0.1:8000/pictures/ ,直接在post中附带如下信息,仅作为图片服务器,写个小小的请求文件

img=open(path,'rb')  #path为02.png图片的路径
files={
     "02.png": img}
r=requests.post(url='http://127.0.0.1:8000/pictures/',files=files)
img.close()

棒棒哒!
当然我们的后端不止如此,后续的完善也会陆续更新在博客,如果您感觉好用,请给卑微的代码搬运工点下一个赞吧。
人生苦短…

你可能感兴趣的:(python,Django,python,django)