zoukankan      html  css  js  c++  java
  • Django(投票程序)

    Django是一个web框架,python编写的。

    MTV模式

    Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同
    -M代表模型(Model ):负责业务对象和数据库的关系映射(ORM)
    -T代表模板(Template):负责如何把页面展示给用户(html)
    -V代表视图(View ) :负责业务逻辑,并在适当时候调用Model和Template
    

      client(客户端)-->请求(url)--> server(服务器的urlconf)-->views(视图,相当于函数,客户机访问url,每次的访问都有相应的函数对应)-->model(数据库,增删改查)-->views(修改数据库后再返回信息给视图,数据交互)-->Template(web页面)-->client

      

    一、创建python的虚拟环境

      (一)配置pip文件

    (django_env) [root@django ~]# cat .pip/pip.conf 
    [global]
    index-url = http://pypi.douban.com/simple
    [install]
    trusted-host=pypi.douban.com
    

       (二)虚拟环境安装

    mkdir pyproject
    cd pyproject/
    python3 -m venv django_env        #在当前目录创建虚拟环境(Django_env 名字可以变)
    source django_env/bin/activate    #激活虚拟环境
    pip install django==1.11.6        #在虚拟环境中安装Django==1.11.6
        (django_env) [root@localhost pyproject]# python  #验证
        Python 3.6.4 (default, Apr 27 2018, 08:26:23) 
        [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux 
        Type "help", "copyright", "credits" or "license" for more information.
        >>> import django 
        >>> django.__version__
        '1.11.6' 
    

    二 、Django项目创建

    django-admin startproject mysite   #创建项目
        (django_env) [root@localhost pyproject]# cd mysite     #Django的目录结构
        (django_env) [root@localhost mysite]# tree
        . 
        ├── manage.py 
        └── mysite 
            ├── __init__.py 
            ├── settings.py 
            ├── urls.py 
            └── wsgi.py 

    mysite:项目的容器。

    manage.py:一个使用的命令行工具,可让你以各种方式与该django项目进行交互(项目的管理目录)

    mysite/__init__.py:一个空文件,告诉python该目录是一个python包。(项目的初始化文件)

    mysite/settings.py:该django项目的设置/配置。(项目的配置文件)

    mysite/urls.py:该django项目的URL声明;一份由django驱动的网站“目录”。(项目的路由文件)

    mysite/wsgi.py:一个WSGI兼容的Web服务器的入口,以便运行你的项目。(将网站部署到web服务器时使用的文件)

     python manage.py runserver 0.0.0.0:8000   #运行项目

     127.0.0.1:8000  #查看项目

     三、Django配置

      (一)创建数据库 

    CREATE DATABASE django DEFAULT CHARSET 'UTF8';
    

      (二)配置 setting.py(配置完成后页面变成中文)

    ALLOWED_HOSTS = ['*']   # 允许所有的客户端访问
    DATABASES = {
        'default': {'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',  
        'USER': 'root',
        'PASSWORD': '数据库root密码',
        'HOST': '127.0.0.1',
        'PORT': '3306',    }
    }
    LANGUAGE_CODE ='zh-hans'   #中文
    TIME_ZONE ='Asia/Shanghai'
    USE_TZ = False
    

       (三)配置__init__.py(要先安装pymysql模块)

    import pymysql
    pymysql.install_as_MySQLdb()
    

       运行查看 

    # 重新运行测试服务器,监听在0.0.0.0的80端口。注意:如果不是root,不能监听1024以下端口
    [root@room8pc16 mysite]# python manage.py runserver 0:80
     

      (四)生成数据  

     [root@room8pc16 mysite]#python manage.py makemigrations  #会生成一些相应的sql语句
     [root@room8pc16 mysite]# python manage.py migrate        #生成表
    

       (五)创建管理员 

    [root@room8pc16 mysite]# python manage.py createsuperuser  #密码要求复杂度和长度
    

       查看页面

     四、使用Django创建应用

      (一)创建应用(对应的一个个的功能模块,使用一个投票为例子)

    [root@room8pc16 mysite]# python manage.py startapp polls   #创建应用(可以集成到任何的一个项目中)
    

       (二)在settings配置文件中声明应用(把应用集成在项目中)

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'polls'           #添加的应用
    ]
    

      (三)授权,把应用的url交给投票应用处理,都在项目下的urls.py的这个文件就会特别大

    polls/urls.py
    from django.conf.urls import url, include
    from django.contrib import adminurlpatterns = [
    # 正则匹配时,从http://x.x.x.x/后面开始算起 
    # 正则匹配时,从http://x.x.x.x/polls
    url(r'^admin/', admin.site.urls), 
    url(r'^polls/', include('polls.urls')), #其中r意思真实字符串相当于shell中的单引号 
    ]
    

       在polls目录下没有urls.py文件就创建一个

    [root@django polls]# touch  urls.py   
    vim polls/urls.py   
    from django.conf.urls import url
    urlpatterns = [
    ]

    五、创建投票首页

      (一)编写url

    from django.conf.urls import url,include
    from django.contrib import admin
    from . import views #.是当前目录的意思(和urls.py同级,也可以from polls import views) urlpatterns = [ url(r'^$', views.index,name='index'), #匹配到空白,都用views.index函数进行响应,那么为函数名字 ]

      (二)编写views视图函数

    def index(request):
    # 用户发起的请求将会作为第一个参数传给函数 (客户端发起请求时可能是 get,put,post,携带的参数或者数据等等 都会作为第一个参数 传给request)
    # 所以函数至少要定义一个参数来接收用户的请求
    # render负责找寻模板文件发送给用户
    return render(request, 'index.html')
    

       (三)编写页面(确定templates模板的位置)

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

       index.html

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>polls</title>
    </head>
    <body>
    <div class="container">
        <h1>polls</h1>
    </div>
    </body>
    </html>
    

     

     六、编写问题页面

      (一)编写urls.py

    urlpatterns = [
        url(r'^$', views.index,name='index'),
        url(r'(d+)/$', views.a,name='a'),
        #d+为匹配数字(+为至少匹配到一个数字)
        # ()为传参(把匹配到的数字作为视图函数a的参数 ) 
    ]
    

       (二)编写views.py

    from django.shortcuts import render
    
    def index(request):
        return render(request,'index.html')
    def a(request,id):  #在urls.py中匹配到的参数的值用变量id接受
        return  render(request,'a.html',{'id':id}) 
      # 字典的内容将会成为模板文件的变量,字典的key是变量名,value是变量值(字典的值成为html的参数)
    

       (三)编写a.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div class="container">
       <h1>{{id}}question</h1>   #在views.py文件中接受的参数,用{{}}表示
    </div>
    </body>
    </html>
    

     七、编写结果页面

      (一)编写urls.py

    urlpatterns = [
        url(r'^$', views.index,name='index'),    #r‘’单引号里面什么也不填写那么就是匹配空串(在任何字符之间都有空串),不管在ip/polls/后面填写什么都将匹配首页
        url(r'(d+)/$', views.a,name='a'),
        url(r'(d+)/result/$', views.result,name='result')
    ]
    

       (二)编写views.py

    from django.shortcuts import render
    
    # Create your views here.
    def index(request):
        return render(request,'index.html')
    def a(request,id):
        return  render(request,'a.html',{'id':id})
    def result(request,id):
        return  render(request,'result.html',{'id':id})
    

       (三)编写result.html

        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>
        <h1>{{id}}result</h1>
    </div>
    </body>
    </html>
    

     八、model模型

    ORM
    object :对象﹐对应django模型中的class
    Relationship:关系﹐对应关系型数据库
    Mapping:映射
    一个class对应数据库中的一张表
    表中的字段与class中的类变量对应
    数据库中的数据类型也与django模型中的类映射
    表中的每个记录都与class的实例对应
    

       (一)编写models.py

    from django.db import models
    
    # Create your models here.
    class Question(models.Model):
        question_text = models.CharField(max_length=200, unique=True)
        pub_date = models.DateTimeField()  #不加Field,没有时分秒
    class Chioce(models.Model):
        chioce_text = models.CharField(max_length=200, unique=True)
        votes = models.IntegerField(default=0)
        question = models.ForeignKey(Question)    #如果想要修改字段名,在配置文件中修改之后,重新生成表
    

       (二)生成表

    python manage.py makemigrations
    python manage.py migrate
    

       (三)将模型加入到后台页面

    # polls/admin.py
    from  django.contrib  import  admin# 在当前目录下的models模块中导入模型
    from .models   import   Question, Choice
    # Register your models here.
    admin.site.register(Question)
    admin.site.register(Choice)
    

     

       解决办法

    class Question(models.Model):
        question_text = models.CharField(max_length=200, unique=True)
        pub_date = models.DateTimeField()
        def __str__(self):     
            return 'question:%s' % self.question_text
    class Chioce(models.Model):
        chioce_text = models.CharField(max_length=200, unique=True)
        votes = models.IntegerField(default=0)
        question = models.ForeignKey(Question)
        def __str__(self):
            return '%s:%s' % return '%s:%s' % (self.question,self.chioce_text)
    

     

     九、Django API(首页)

       (一)在views文件中把问题取出来传给html

    # polls/views.py
    from django.shortcuts import render
    from .models import Question 
    def index(request):
      questions = Question.objects.order_by('-pub_date')
      returnrender(request, 'index.html', {'questions': questions})
    

       (二)编辑index.html

    <!DOCTYPEhtml>
    <htmllang="en">
    <head>
    <metacharset="UTF-8">
    <title>投票首页</title>
    </head>
    <body>
    <div class="container">
        <div class="content">
            <h1>投票首页</h1>
            <ol>            
                {% for question in questions %}  
                <li>
                    <a href="{% url 'a' question.id %}" target="_blank">
    #question_id是views.py中的d+这个参数,数据库中没有指定主键时Django会自动创建主键,question_id就是问题的id号 {{ question.question_text }}</a>      {{ question.pub_date }} </li> {%endfor%} </ol> </div> </div> </body> </html>

       (三)可以添加轮播图

    <div class="container">
         <div id="linux-carousel" class="carousel slide"> 
            <ol class="carousel-indicators"> 
                <li class="active" data-target="#linux-carousel" data-slide-to="0"></li>  #轮播图下面的小圆点
                <li data-target="#linux-carousel" data-slide-to="1"></li> 
                <li data-target="#linux-carousel" data-slide-to="2"></li> 
            </ol>
             <div class="carousel-inner"> 
                <div class="item active"> 
                    <a href="http://www.sogou.com" target="_blank"> 
                        <img src="{% static 'imgs/first.jpg' %}"> 
                    </a> 
                </div> 
                <div class="item">
                     <img src="{% static 'imgs/second.jpg' %}">
                </div>
                 <div class="item"> 
                    <img src="{% static 'imgs/third.jpg' %}">
                </div>    
            </div> 
            <a href="#linux-carousel" data-slide="prev" class="carousel-control left"> <span class="glyphicon glyphicon-chevron-left"></span>    #向左翻
    制作投票详情页    
             </a> 
            <a href="#linux-carousel" data-slide="next" class="carousel-control right"> <span class="glyphicon glyphicon-chevron-right"></span>   #向右翻
            </a>
         </div>        
    <script src="{% static 'js/jquery.min.js' %}"></script>    #要有JS代码才能实现轮播图
    <script src="{% static 'js/bootstrap.min.js' %}"></script> 
    <script type="text/javascript">
    

       (四)模板继承(为了避免一些网页的重复代码)

        1.复制index.html一本命令为bak.html

    # 在basic.html中,将个性(不相同)内容用block替代 
    {% load static %} 
    <!DOCTYPE html> 
    <html lang="en"> 
    <head><meta charset="UTF-8">
     <title>{% block title %}{% endblock %}</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> 
    </head>
     <body> 
    <div class="container"> 
        <div id="linux-carousel" class="carousel slide">
             <ol class="carousel-indicators">
                 <li class="active" data-target="#linux-carousel" data-slide-to="0"></li> 
                 <li data-target="#linux-carousel" data-slide-to="1"></li> 
                 <li data-target="#linux-carousel" data-slide-to="2"></li> 
            </ol> 
            <div class="carousel-inner"> 
                <div class="item active"> 
                <a href="http://www.sogou.com" target="_blank"> 
                    <img src="{% static 'imgs/first.jpg' %}">   #图片放在polls下static目录的imgs目录中
                </a> 
            </div>     
            <div class="item">     
                <img src="{% static 'imgs/second.jpg' %}">     
            </div> 
            <div class="item"> 
                <img src="{% static 'imgs/third.jpg' %}"> 
            </div> 
        </div> 
        <a href="#linux-carousel" data-slide="prev" class="carousel-control left"> <span class="glyphicon glyphicon-chevron-left"></span>
    制作投票详情页 </a> 
        <a href="#linux-carousel" data-slide="next" class="carousel-control right"> <span class="glyphicon glyphicon-chevron-right"></span> 
        </a> 
    </div> 
        {% block content %}{% endblock %} 
    <script src="{% static 'js/jquery.min.js' %}"></script> 
    <script src="{% static 'js/bootstrap.min.js' %}"></script> 
    <script type="text/javascript"></script> 
    </body>
    </html>    
        
    

       2.index.html

    # 修改index.html,把共性内容删除,个性内容写到对应的block中 
    {% extends 'bak.html' %}  #继承
    {% load static %} 
    {% block title %}投票首页{% endblock %} 
    {% block content %} 
    <div class="content h4"> 
        <h1 class="text-center text-warning">投票首页</h1> 
        <ol style="margin: 20px 0"> 
            {% for question in questions %} 
            <li><a href="{% url 'detail' question.id %}" target="_blank"> 
            {{ question.question_text }} </a> {{ question.pub_date }} 
            </li> {% endfor %} 
        </ol> 
    </div> 
    {% endblock %}  
    

    十、制作a.html(第二个页面)

      (一)编辑views.py

    from django.shortcuts import render
    from .models import Question, Chioce
    # Create your views here.
    def index(request):
        d = Question.objects.order_by('-pub_date')
        return render(request,'index.html',{'d':d})
    def a(request,question_id):
        c = Question.objects.get(id=question_id)
        return  render(request,'a.html',{'id':c})
    def result(request,id):
        return  render(request,'result.html',{'id':id})
    

       (二)编辑a.html(取出选项)

    {% extends 'bak.html'%}
    {% load static %}
    {% block title%}polls{%endblock%}
    {% block content%}
    <div class="container">
       <h1>{{ id.id }}</h1>
    </div>
    <div class="content h4 text-warning"  >
        <h1 class="text-center">chioce</h1>
        <h2>{{ id }}</h2>
        <form action="">
          {% csrf_token %} #安全选项 {% for i in id.chioce_set.all %} <div class="radio"> <label > <input type="radio" name="chioce_id" value="{{ chioce_id }}"> {{ i.chioce_text }} </label> </div> {% endfor %} </form> </div> <div class="group"> <input class="btn btn-primary" tpye="submit" value="submit"> </div> {%endblock%}

    十一、实现投票功能(数据库添加删除)

      实现数据库的增删改查。执行函数对model模型的操作(url-->views-->model)

      (一)配置urls.py

    from django.conf.urls import url,include
    from django.contrib import admin
    from . import  views
    
    urlpatterns = [
        url(r'^$', views.index,name='index'),
        url(r'(d+)/$', views.a,name='a'),
        url(r'(d+)/result/$', views.result,name='result'),
        url(r'(d+)/vote/$', views.vote,name='vote'),
    ]
    

       (二)配置views.py

    from django.shortcuts import  render, redirect
    from .models import Question, Chioce
    # Create your views here.
    def index(request):
        d = Question.objects.order_by('-pub_date')
        return render(request,'index.html',{'d':d})
    def a(request,question_id):
        c = Question.objects.get(id=question_id)
        return  render(request,'a.html',{'id':c})
    def result(request,id):
        return  render(request,'result.html',{'id':id})
    def vote(request,id):   
        d = Question.objects.get(id=id)    #取出问题
    # 当用户提交表单时,request.POST是一个字典,里面记录了与POST相关的数据 
    # choice_id是detail.html页面中单选按钮的name,值是选项的id(value的值)
        chioce_id = request.POST.get('chioce_id')   #取出name的值
        chioce  = d.chioce_set.get(id=chioce_id)   #取出对用id的项
        chioce.votes += 1
        chioce.save()
    # 这里返回使用的不是render,因为render直接返回页面,URL不变,也就是http://x.x.x.x/polls/2/vote显示的是2号问题的投票结果,这是不合理的应该由http://x.x.x.x/polls/2/result/显示投票结果。所以使用redirect
        return redirect('result',id)
    

       (三)配置a.html

    {% extends 'bak.html'%}
    {% load static %}
    {% block title%}polls{%endblock%}
    {% block content%}
    <div class="container">
       <h1>{{ id.id }}</h1>
    </div>
    <div class="content h4 text-warning"  >
        <h1 class="text-center">chioce</h1>
        <h2>{{ id }}</h2>
        <form action="{% url 'vote' id.id %}" method="post">
            {% csrf_token %}
            {% for i in id.chioce_set.all %}
                <div class="radio">
                    <label >
                        <input type="radio" name="chioce_id" value="{{ i.id }}">
                        {{ i.chioce_text }}
                    </label>
                </div>
            {% endfor %}
            <div class="form-group">
                <input  class="btn btn-primary" type="submit" value="submit">
            </div>
        </form>
    </div>
    
    {%endblock%}
    

     十二、配置result.html

      (一)views.py

    from django.shortcuts import  render, redirect
    from .models import Question, Chioce
    # Create your views here.
    def index(request):
        d = Question.objects.order_by('-pub_date')
        return render(request,'index.html',{'d':d})
    def a(request,question_id):
        c = Question.objects.get(id=question_id)
        return  render(request,'a.html',{'id':c})
    def result(request,id):
        d = Question.objects.get(id=id)
        return  render(request,'result.html',{'id':d})
    def vote(request,id):
        d = Question.objects.get(id=id)
        chioce_id = request.POST.get('chioce_id')
        chioce  = d.chioce_set.get(id=chioce_id)
        chioce.votes += 1
        chioce.save()
        return redirect('result',id)
    

       (二)配置resul.html

    {% extends 'bak.html'%}
    {% load static %}
    {% block title%}投票结果{%endblock%}
    {% block content%}
    <div>
        <h1 class="text-center">{{ id.id }}投票结果</h1>
        <table class="table table-striped table-hover">
            <thead class="bg-primary">
                <tr>
                    <td colspan="2">{{ id.question_text }}</td>
                </tr>
            </thead>
            {% for i in id.chioce_set.all %}
            <tr>
                <td>{{ i.chioce_text }}</td>
                <td >{{ i.votes }}</td>
            </tr>
            {%endfor%}
        </table>
    
    </div>
    {%endblock%}
    
  • 相关阅读:
    截除数值,分别获取数据与单位
    angularjs判断对象值是否存在
    angularjs文件上传实例
    获取Zxing.net 中所有barcodeformat
    创建QR CODE
    QR Code的容错级别
    验证QR Code版本
    Web API返回自定义数据给客户端
    理解Hive 不同组件的功能
    tcpdf中文解决方案
  • 原文地址:https://www.cnblogs.com/zshBlos/p/14257954.html
Copyright © 2011-2022 走看看