zoukankan      html  css  js  c++  java
  • Djangoの1

    有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 %}
                
            {% 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=" 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: ovel路径下进入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; 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>
  • 相关阅读:
    区别@ControllerAdvice 和@RestControllerAdvice
    Cannot determine embedded database driver class for database type NONE
    使用HttpClient 发送 GET、POST、PUT、Delete请求及文件上传
    Markdown语法笔记
    Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
    Mysql 查看连接数,状态 最大并发数(赞)
    OncePerRequestFilter的作用
    java连接MySql数据库 zeroDateTimeBehavior
    Intellij IDEA 安装lombok及使用详解
    ps -ef |grep xxx 输出的具体含义
  • 原文地址:https://www.cnblogs.com/scrooge/p/7693891.html
Copyright © 2011-2022 走看看