scrooge
有ip无路由是404,ip也无是无法访问此网站。url中?前的是路由,?后是GET请求的各组参数。
 
子项目和子应用下的两类urls.py:[]内的各个路由函数url,其首参网址的开头无/,结尾有/。
views中的各函数、templates下的xxx.html,所出现的各相对路径:项目的根目录(即与manage.py同级的文件夹或文件)开头不加/,次级目录开头要加/;url若拼接ip则开头加/,拼接所在函数所响应的路由则开头不加/。
 
settings.py底的STATIC_URL = \'/static/\',前后都有/:
①开头有/:static文件夹在子应用下而非总项目的根下;拼接的是ip②结尾有/:尾部要接受css等子文件(夹)的拼接。
 
设计个有远见的数据库=项目完成了一半=几千行代码。既让当前的代码活事半功倍,又减少日后修修补补的次数和面积。数据库的架构是机密,竞争对手看到后,或能山寨出相似的项目。

引入markdown:
www.zhidaow.com/post/django-custom-template-tag-markdown。
**************************分割线**************************
三大web框架的请求:
请求的参数为input标签(type为text,password,checkbox等)的name属性,返回为value属性的值。
 
tornado用方法self.get_argument(\'name值\'),另俩用{}:request.xx[\'name\']或request.xx.get(\'name\')。
 
①tornado:get和post都是self.get_argument(\'name属性的值\',default=None)。
②flask:get请求用request.args[\'name\'],post用request.form[\'name\']。
③django:request.GET[\'name\'],所求在网址的?后;request.POST[\'name\'],request.FILES[\'type为file…\'],所求都在postData;request.META[\'某个请求头如HTTP_REFERER\']。
**************************分割线**************************
html模板:①{{变量}};
②{% 语法如if、for…in…、with…as…等;或函数如load static from staticfiles、csrf_token等 %}
 
django和flask的 html模板中的 循环或判断:
(tornado例外,结尾全是{% end %},属性用d[\'key\']而非d.key)
 
{% for country in countries %}
    {% for city in country.cities %}
        国家#{{forloop.parentloop.counter}}:{{city}}
        {% if not forloop.last %}
            ,
        {% else %}
            \n
        {% endif %}
    {% endfor %}
{% endfor %}
****************************************分割线****************************************
django做个电影网站:
 
①E盘下建个movie文件夹→PyCharm新建项目选Django→location改为E:\movie→More Settings的Application写个dy;
 
注:PyCharm新建好django项目后,启动项目是按绿方块dj+根目录(如本例的movie)右侧的绿三角,而非我习惯的Run context configuration。
**************************分割线**************************
②项目文件夹movie:
 
配置文件settings.py:
 
DEBUG = True在部署到Linux前要改为False。INSTALLED_APPS尾已自动添加了dy…,不理会;若新建应用,则模仿dy…添加。
LANGUAGE_CODE = \'zh-hans\'
TIME_ZONE = \'Asia/Shanghai\'
 
DATABASES = {
    \'default\': {
        \'ENGINE\': \'django.db.backends.mysql\',
        #以下四项,和软件Navicat for MySQL的连接界面一样
        \'HOST\': \'mysql.litianqiang.com\',  #潭州的远程mysql
        \'PORT\': \'7150\',  #mysql默认端口3306;在django是str,MySQLdb是int
        \'USER\': \'movie\',
        \'PASSWORD\': \'……()\',    #隐藏……处,用的院长的绰号
        \'NAME\': \'movie\',    #潭州学院一远程数据库的名字
    }
}
 
sessions禁用:注释此行\'django.contrib.sessions.middleware.SessionMiddleware\',
 
sessions的3种存储方式:
SESSION_ENGINE=\'django.contrib.sessions.backends.db\'    #默认存在数据库
SESSION_ENGINE=\'django.contrib.sessions.backends.cache\'    #存在缓存
SESSION_ENGINE=\'django.contrib.sessions.backends.cached_db\'    #优先缓存,次选库
***************分割线***************
路由文件urls.py:
url的2参有两种写法:url(\'正则\',views.视图函数名)、大型的url(\'正则\',include(\'应用名.urls\'))。
 
from django.conf.urls import url,include
from django.contrib import admin
from dy import views
 
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^$\',views.index),  #首页是^$;2参是视图函数名,而非补个()的返回值
    url(r\'^cy/\',views.chengy,name=\'xm\'),    #给路由起个别名,方便视图调用
    url(r\'^cy/\', include(\'dy.urls\')),   #使dy下urls.py内的各url的首参,拼接ip/cy/,而非ip/
    url(r\'^cy(x)/(y)/\',views.info),   #def info(request,n,m):,x,y的值按位置传参给n,m
    url(r\'^cy(?P<id>\w+)/\',views.stu),   #def stu(request,id):,\w+的值按参数名传给id
]
**************************分割线**************************
③应用文件夹dy:
 
路由文件urls.py:本例的网址少,不必牛刀杀鸡建此文件,只是举个例子
 
from django.conf.urls import url
from dy import views
 
urlpatterns = [
    url(r\'^$\',views.indexDY),
    url(r\'^666/\',views.留空),
]
***************分割线***************
和数据库交互(俗称ORM:Object Relational Mapping)的models.py:
 
在E:\movie路径下进入cmd:python manage.py inspectdb > dy/models.py
执行后settings中所配数据库movie中的各表,以class的形式(表名删_,首字母大写)自动写入dy/models.py。
 
各类字段:
参数null默认False不许为空,参数unique若设为True则该字段列无重复。
自增主键models.AutoField(primary_key=True),布尔BooleanField,整数IntegerField,浮点数FloatField,指定总位数和小数位数的models.DecimalField(max_digits=7, decimal_places=3)。
字串字段,限制字数的短文本用models.CharField(max_length=9),一般超4000字符的大文本用TextField。
时间字段DateField或TimeField或DateTimeField,加参数auto_now=True则各行记录的该字段时间值为最后1次修改的,auto_now_add=True则为固定的创建时间。
外键字段classID=models.ForeignKey(\'类名如Classes\'),在Classes-Students(两张数据表classes和students)的Students类一方定义。
 
Egの外键使用,html中遍历各个班里的学生:
{% for stu in students %}
    {{ stu.studentName }}∈{{ stu.classID.className }}
{% endfor %}
<br><hr><br>    //空行br、横线hr、无序列表ul
{% for c in classes %}
    班级{{ c.className }}有以下学生:
    <ul>
        {% for stu in c.students_set.all %}    //班级外键.学生表名后加_set.all,.py内all后有()
            <li>{{ stu.studentName }}</li>
        {% endfor %}
    </ul>
{% endfor %}
***************分割线***************
各路由网址呈现什么内容的文件views.py:
 
from django.shortcuts import render  #return render(request,\'index.html\',context=context)
from django.shortcuts import redirect    #return redirect(\'/login/\')
from django.http import HttpResponse    #return HttpResponse(\'<h1>hello,world</h1>\')
from django.http import JsonResponse    #return JsonResponse({\'x\':\'hello\',\'y\':\'world\'})
from dy.models import DyDy    #导入movie库中电影数据源所在的那张表
 
def chengy(request):
    #.get()取键值,若无不报错;多个name为x(如type="checkbox"的各标签),则用.getlist(\'x\')
    words=request.POST.get(\'keywords\')
 
    #视图中session的使用:
    request.session.get(\'a\',\'\')    #获取session中session_key为a的session_data
    request.session[\'a\']=1  #设置键a的值
    request.session.set_expiry(600)  #过期单位秒,默认2周,0在关浏览器时,None永不过期
    del request.session[\'a\']    #删除session中的键a
    request.session.clear()    #各session_key的session_data置为\'\'
    request.session.flush()    #删除session
 
    #请求的:request.COOKIES、参数获取.GET及.POST、方式.method、编码.encoding
    response=HttpResponse(f\'请求的路径:{request.path}\')
    response.set_cookie(\'name\',\'jack\',expires=60*60*24)  #设置coocie的键、值、有效期24h
    return response
 
def index(request):
    kw=request.POST.get(\'kw\')
    if kw:
        #增=DyDy();增.title=\'2012\';增.link=\'http://…\';增.save()
        #DyDy.objects.all().order_by(\'-title\')[:50].delete()    #按title降序后,删前50行记录
        #改=DyDy.objects.get(id=1);改.title=\'乱\';改.save()  #改这条记录(若无则抛出异常)的title
        查=DyDy.objects.filter(title__icontains=kw)[:9]   #标题含关键词的前9条,若无则返回空[]
    context={\'movies\':查}
    return render(request,\'index.html\',context=context)
***************分割线***************
应用文件夹dy下新建个templates文件夹,其内新建个index.html:
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>电影下载-首页</title>
</head>
<body>
<form action="/" method="post">
    {% csrf_token %}    <!--跨域攻击;新浪上写博客不支持半角<符和autocomplete单词-->
    <input type="text" name="kw" style="width: 500px" auto¥complete="off">
    <input type="submit" value="搜索电影">
</form><br>
{% if movies %}
    {% for movie in movies %}
    <li><a href="{{ movie.link }}">{{ movie.title }}</a></li>
    {% endfor %}
{% endif %}
</body>
</html>
****************************************分割线****************************************
开发网盘:
 
①E盘下建个wangpan文件夹→……Application写个disk;
***************分割线***************
②项目文件夹wangpan:
 
__init__.py:
import pymysql
pymysql.install_as_MySQLdb()
 
settings.py:
DATABASES = {
    \'default\': {
        \'ENGINE\': \'django.db.backends.mysql\',
        \'HOST\':\'localhost\',\'PORT\':\'3306\',\'USER\':\'chengy\',\'PASSWORD\':\'\',
        \'NAME\': \'网盘\'
    }
}
 
urls.py:
from django.conf.urls import url
from django.contrib import admin
from disk import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^$\', views.index,name=\'index\'),
    url(r\'^upload/$\', views.upload,name=\'upload\'),
    url(r\'^s/(\w{32})/$\', views.content),   #路由网址中的()(),是content函数的2参、3参等
    url(r\'^file/.*?$\', views.download,name=\'download\'),
]
***************分割线***************
③应用文件夹disk:
 
models.py:
from django.db import models
class FileInfo(models.Model):
    # id=models.AutoField(primary_key=True)   #默认创建主键自增字段id
    user=models.CharField(max_length=20,null=False)
    fileName=models.CharField(max_length=30,null=False)
    fileSize=models.IntegerField(null=False)
    fileMd5=models.CharField(max_length=32,null=False)
 
在E:\wangpan进入cmd,依次执行如下两句,用models.py的各类,生成mysql的网盘库的各表:
python manage.py makemigrations
python manage.py migrate
******分割线******
views.py:
from django.shortcuts import render
from django.http import HttpResponse,HttpResponseRedirect
import hashlib
from disk.models import FileInfo
 
def index(request):
    return render(request,\'index.html\')
 
def upload(request):
    #在用户电脑上读取文件并计算MD5值,而非上传到网盘服务器后才计算
    myFile=request.FILES.get(\'upfile\')
    if not myFile:  #print(myFile)
        return HttpResponse(\'没上传文件\')
    file=myFile.read()
    if not file:
        return HttpResponse(\'不能上传空文件\')
    fileName=myFile.name
    fileSize=myFile.size
    fileMd5=hashlib.md5(file).hexdigest()
    existed=FileInfo.objects.filter(fileMd5=fileMd5)
    if existed:
        FileInfo(fileName=fileName, fileSize=fileSize, fileMd5=fileMd5).save()
        # return HttpResponse(\'文件成功秒传\')   #AttributeError \'tuple\'  no attribute \'get\'
        return HttpResponseRedirect(\'/s/{}\'.format(fileMd5))    #拼接的是域名,s前有/
    with open(\'file/{}\'.format(fileMd5),\'wb\') as f: #file,是和manage.py同级的文件夹,前无/
        f.write(file)
    FileInfo(fileName=fileName, fileSize=fileSize, fileMd5=fileMd5).save()
    # return HttpResponse(\'文件上传完成\')
    return HttpResponseRedirect(\'/s/{}\'.format(fileMd5))
 
def content(request,fileMd5):
    fileInfo=FileInfo.objects.filter(fileMd5=fileMd5)   #类似正则的findall,提取某行记录要加[0]
    if not fileInfo:
        return HttpResponse(\'该文件不存在或已被删除\')
    context={
        \'fileName\':fileInfo[0].fileName,
        \'fileSize\':fileInfo[0].fileSize,
        \'fileUrl\':\'/file/{}\'.format(fileInfo[0].fileName)}  #下载时默认的文件名,取末/后的字串
    return render(request,\'content.html\',context=context)
 
def download(request):
    referer=request.META.get(\'HTTP_REFERER\')    #获取来路,只在部署到Linux前用
    if not referer:
        return HttpResponse(\'该文件不存在或已被删除\')  #防止复制下载网址来直接下载
    fileMd5=referer[-33:-1]
    fileInfo=FileInfo.objects.filter(fileMd5=fileMd5)
    if not fileInfo:
        return HttpResponse(\'该文件不存在或已被删除\')
    file=open(\'file/{}\'.format(fileMd5),\'rb\').read()
    response=HttpResponse(file) #HttpResponse的一个最大用处:下载流数据
    response["Content-type"]="application/octet-stream"
    return response
***************分割线***************
④index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="/upload/" method="post" enctype="multipart/form-data">
    {% csrf_token %}    <!--跨域攻击-->
    <input type="file" name="upfile">
    <input type="submit" value="上传">
</form>
</body>
</html>
 
content.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件下载</title>
</head>
<body>
<li>文件名:{{ fileName }}</li>
<br>    <!--换行符-->
<li>文件大小:{{ fileSize }}</li>
<br>
<li><a href="{{ fileUrl }}">点击下载</a></li>
</body>
</html>
****************************************分割线****************************************
小说网站:
 
①E盘下建个novel文件夹→……Application写个xs;
***************分割线***************
②settings.py:
DATABASES = {
    \'default\': {
        \'ENGINE\': \'django.db.backends.mysql\',
        \'HOST\': \'mysql.litianqiang.com\',\'PORT\': \'7150\',
        \'USER\': \'novel\',\'PASSWORD\': \'……()\',    #隐藏……处,李院长用的他的绰号
        \'NAME\': \'novel\',
    }
}
 
urls.py:
from django.conf.urls import url
from django.contrib import admin
from xs import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^$\', views.index,name=\'index\'),
]
***************分割线***************
③models.py:
在E:\novel路径下进入cmd:python manage.py inspectdb > xs/models.py
 
views.py:
from django.shortcuts import render
from xs.models import NovelCopy
def index(request):
    novelsHot=NovelCopy.objects.filter().order_by(\'?\')[:4]  #ORM模型,用?表示随机排序
    novelsXH=NovelCopy.objects.filter(sort=\'玄幻\').order_by(\'?\')[:4]
    novelsWX=NovelCopy.objects.filter(sort=\'武侠\').order_by(\'?\')[:5]
    context = {\'novelsHot\':novelsHot,\'novelsXH\':novelsXH,\'novelsWX\':novelsWX}
    return render(request,\'index.html\',context=context)
***************分割线***************
④index.html:
 
{% load staticfiles %}   <!--若static文件夹及settings.py末尾均改了名,html中只需改这1处-->
<!doctype html>
<html>
  <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="Keywords" content=""/><meta name="description" content=""/>
    <title>Python探索馆 - Slice</title>
    <link rel="stylesheet" href="{% static \'css/style.css\' %}" /></head>
 
<body>
<div class="full-pic"></div>    <!--===== Full Screen BG =====-->
 
<header class="header"> <!--===== Begin Header =====-->
  <div class="fixed-head" style="position: fixed; width: 100%;">
    <div class="wrap1000 head-wrap">
      <div class="logo"><a href="detail.html">Python学院图书馆</a></div>
      <div class="nav"><ul class="nav-list">
          <li><a href="detail.html"><span>首页</span></a></li>
          <li><a href="detail.html"><span>玄幻</span></a></li>
          <li><a href="detail.html"><span>修仙</span></a></li></ul></div>
 
      <div class="search"><form action="search.html" method="get" target="_blank">
          <input name="kw" placeholder="搜索书名" type="text" maxlength="10" />
          <input id="search-submit-btn" type="submit"/>
          <label for="search-submit-btn"><i class="iconfont icon-search"></i></label>
        </form></div>
    </div></div>
</header>
 
<!--===== Begin Main =====-->
<section class="main"><div class="main-wrap wrap1000"><div class="hot-section"><div class="hot-content">
        <div class="hot-shadow"><div class="hot-title">最热</div></div>
        <div class="banner">    <!-- 1、banner -->
          <ul class="banner-imgs">    <!--static/img文件夹下放了几张图片,就写几个li标签-->
              <li><a href="detail.html"><img src="{% static \'img/1.jpg\' %}"/></a></li>
          </ul>
          <div class="control-page">
            <a class="iconfont icon-bannerzuo" href=";"></a>
            <a class="iconfont icon-banneryou" href=";"></a>
          </div>
        </div>
 
        <div class="hot-recommend"><ul class="hot-list">    <!-- 2、hot -->
            {% for novel in novelsHot %}
            <li><a href="detail.html"><div><img src="{{ novel.novelimg }}"/></div>
                <p>{{novel.novelname}}<span class="author">{{novel.author}} 著</span>
                  <span class="book-description">
<!--|safe把空格、换行等标点转为正常字符;|chuncatechars:\'数字\',把超出的字数以仨点替之-->
                    {{ novel.description|safe|truncatechars:\'90\' }}
                  </span></p></a></li>
            {% endfor %}</ul></div>
 
        <div class="xuanhuan">  <!-- 3、Xuanhuan -->
          <div class="xuanhuan-title">
            <span>玄幻</span><p class="txt">Fantasy</p><p>Novel</p>
            <span class="more"><a href="more.html">更多>></a></span>
          </div>
          <div class="wrap890 xuanhuan-wrap"><ul class="book-list">
            {% for novel in novelsXH %}
                <li class="book"><div class="book-wrap">
                  <a class="cover" href="detail.html"><img src="{{ novel.novelimg }}" width="136" height="180" /></a>
                  <div class="book-presentation"><h2><a href="detail.html">{{ novel.novelname }}</a></h2>
                    <p class="book-info"><span>{{ novel.sort }}</span><span>{{ novel.state }}</span></p>
                    <p class="book-author"><a href=";">作者:<span>{{ novel.author }}</span></a></p>
                    <p class="desc">{{ novel.description|safe|truncatechars:\'90\' }}</p>
                  </div></div></li>
            {% endfor %}</ul></div>
        </div>
 
        <!-- 4、WuXia 仿照第3条的玄幻-->
 
      </div></div></div></section>  <!--=====End Main=====-->
 
<footer class="footer"> <!--=====Begin Footer=====-->
  <div class="wrap1000 footer-wrap">
    <div class="logo-footer"><a href="detail.html">
        <img src="{% static \'img/footer_logo.png\' %}" alt="" width="50"/>
        <span class="footer-txt">世界你好</span></a>
      <span class="footer-font">TAN ZHOU PYTHON COLLEGE</span></div>
    <div class="copy-right"><p>本站仅供技术学习使用,勿用商业</p>
      <p>Copyright © 2017 All Rights Reserved 世界你好</p></div>
    </div></footer> <!--=====End Footer=====-->
<script src="{% static \'js/index.js\' %}"></script>  <!-- Main Plugin -->
 
</body></html>

分类:

技术点:

相关文章:

  • 2021-07-29
  • 2021-06-21
  • 2021-12-21
  • 2021-09-09
  • 2021-10-21
  • 2021-09-23
  • 2021-08-15
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-26
  • 2021-06-18
  • 2021-12-07
  • 2021-11-05
相关资源
相似解决方案