美文网首页潘森sibada
django搭建web网站

django搭建web网站

作者: 星际探索者 | 来源:发表于2020-05-13 11:01 被阅读0次

    首先我们聊一下django的前世今生,据说03年的时候下面这几家公司开始使用python构建网站,
    Lawrence Journal-World newspaper
    Adrian Holovaty
    Simon Willison
    这几家公司的工作性质都有一个共同的特点就是每天需要不停的处理各类新闻事务、作品,话说当时编辑部门提出的需求变化之快让技术部门毫无招架之力,所以django就在这年诞生了,django与其快速开发的特性,方便的model管理,MTV模型(model-template-view)成就了djano在python web领域的霸主地位,下面的演示将带大家一起领略django的神奇魅力。

    步骤

    1、环境准备,安装django3.0版本,mysql驱动
    2、创建一个项目,并设置settings
    3、初始化数据库,创建django超级用户用于后台model管理
    4、创建一个app,在settings注册app,在models.py创建模型,并在admin.py注册model,生成迁移文件并同步到数据库
    5、app下views创建视图层
    6、app下创建urls路由配置文件,并为视图层配置跳转
    7、app下创建templates/appName/结构目录,并在目录下创建视图层对应的html模板
    8、效果展示
    9、使用django view模板,简化代码量
    10、static静态资源使用
    

    1、安装django3.0版本,指定安装源为国内豆瓣源

    pip install django==3.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
    pip install  -i http://pypi.douban.com/simple --trusted-host pypi.douban.com mysqlclient
    

    django-admin startproject djangotest

    2、settings.py设置

    # 设置显示语言
    from django.utils.translation import gettext_lazy as _
    LANGUAGES = [
        ('zh-Hans', _('Chinese')),
    ]
    LANGUAGE_CODE = 'zh-Hans'
    
    # 设置时区
    TIME_ZONE = 'Asia/Shanghai'
    
    # 设置数据库,默认使用sqlite3,这里使用mysql
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'django',
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        }
    }
    

    3、初始化数据库
    3-1 在数据库执行下面命令创建django库

     create database django default charset utf8;
    

    3-2 在项目下执行python manage.py migrate 同步django后台管理的相关表


    image.png
    image.png

    3-3 创建超级用户用于django后台登陆,管理model

    python manage.py createsuperuser
    
    image.png

    3-4 启动项目,访问http://127.0.0.1:8000,http://127.0.0.1:8000/admin

    python manage.py runserver
    
    image.png
    image.png
    image.png
    image.png

    4、创建一个app,在settings注册app,在models.py创建模型,并在admin.py注册model,生成迁移文件并同步到数据库

    4-1 创建一个民意调查的app,需求,我们需要对网友关注的问题进行网络投票,一个问题对应多种答案,每个网民可以对其中的一个答案进行投票
    python manage.py startapp polls

    image.png

    4-2 在settings.py INSTALLED_APPS增加polls app

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'polls.apps.PollsConfig',
    ]
    

    4-3 models.py创建model模型

    from django.db import models
    
    # 继承Model,django会自动识别并在数据库创建该表
    class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')
        
        # 用于django后台显示该字段
        def __str__(self):
            return self.question_text
    
    class Choice(models.Model):
        # 一对多关系,删除question时,对应的choice也会删除
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        choice_text = models.CharField(max_length=200)
        votes = models.IntegerField(default=0)
    
        def __str__(self):
            return self.choice_text
    

    4-4 admin.py注册 model

    from django.contrib import admin
    from .models import Question, Choice
    admin.site.register(Question)
    admin.site.register(Choice)
    
    

    4-5 生成迁移文件,并同步到数据库

    python manage.py makemigrations
    python manage.py migrate
    
    
    image.png
    image.png

    4-6 后台可以看到已更新刚注册的model


    image.png

    4-7 增加几个quesiton,并对question设置几个选项


    image.png
    image.png
    image.png
    image.png
    image.png

    5、polls/views.py创建视图层

    from django.shortcuts import render, get_object_or_404
    from django.http import HttpResponseRedirect
    from .models import Question, Choice
    from django.urls import reverse
    
    # 获取最近相关的5个问题
    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        context = {'latest_question_list': latest_question_list}
        return render(request, 'polls/index.html', context)
    
    # 投票页面
    def detail(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/detail.html', {'question': question})
    
    # 投票处理
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            # POST请求的key需要与detail.html input name属性保持一致
            selected_choice = question.choice_set.get(pk=request.POST['choice'])
        except(KeyError, Choice.DoesNotExist):
            return render(request, 'polls/detail.html',{
                'question':question,
                'error_message': "You didn't select a choice"
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
    
    # 投票结果展示
    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/results.html', {'question':question})
    

    6、app下创建urls.py路由配置文件,并为视图层配置跳转

    from django.urls import path
    from . import views
    
    # app命名空间,django一个项目包含n个app,使用命名可以可以对url进行分类
    app_name = 'polls'
    urlpatterns =  [
        path('', views.index, name='index'),
        path('<int:question_id>/', views.detail, name='detail'),
        path('<int:question_id>/vote/', views.vote, name='vote'),
        path('<int:question_id>/results/', views.results, name='results'),
    ]
    

    项目路由配置

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('polls/', include('polls.urls')),
    ]
    
    image.png

    7、app下创建templates/appName/结构目录,并在目录下创建视图层对应的html模板,下面的是django模板的固定写法.

    image.png

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {% if latest_question_list %}
        <ul>
            {% for question in latest_question_list %}
                <li> <a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a> </li>
            {% endfor %}
        </ul>
    {% else %}
        <p> don't have resources </p>
    {% endif %}
    </body>
    </html>
    

    detail.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1> {{ question.question_text }} </h1>
    {% if error_message %} <p> <strong> {{ error_message }} </strong> </p> {% endif %}
    <form action="{% url 'polls:vote' question.id %}" method="post">
        {% csrf_token %}
        <ul>
            {% for choice in question.choice_set.all %}
                <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
                <label for="choice{{ forloop.counter }}"> {{ choice.choice_text }} </label>
            {% endfor %}
        </ul>
        <input type="submit" value="Vote">
    </form>
    
    </body>
    </html>
    

    results.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1> {{ question.question_text }} </h1>
    
    <ul>
        {% for choice in question.choice_set.all %}
            <li> {{ choice.choice_text }} -- {{ choice.votes }} </li>
        {% endfor %}
    </ul>
    <a href="{% url 'polls:vote' question.id %}"> Vote again? </a>
    </body>
    </html>
    

    8、效果展示

    index首页


    image.png

    投票页面


    image.png

    结果展示页面


    image.png

    9、django为单个model或model list集合提供了模板,对于上面的index,detail,results,都是查询model或model集合,下面对这些view进行简化

    9-1 修改views.py, urls.py如下

    views.py
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    from django.shortcuts import get_object_or_404, render
    from django.views import generic
    from .models import Question, Choice
    
    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_question_list'
    
        def get_queryset(self):
            return Question.objects.order_by('-pub_date')[:5]
    
    # django DetailView模板 默认返回的是<app name>/<model name>_detail.html,你甚至可以不指定template_name,
    # 只要你按照相应的规则创建html
    class DetailView(generic.DetailView):
        model = Question
        template_name = 'polls/detail.html'
    
    class ResultsView(generic.DetailView):
        model = Question
        template_name = 'polls/results.html'
    
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            # POST请求的key需要与detail.html input name属性保持一致
            selected_choice = question.choice_set.get(pk=request.POST['choice'])
        except(KeyError, Choice.DoesNotExist):
            return render(request, 'polls/detail.html',{
                'question':question,
                'error_message': "You didn't select a choice"
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
    
    
    urls.py
    from django.urls import path
    from . import views
    
    app_name = 'polls'
    
    # 这里使用主键代替上面的question_id
    urlpatterns = [
        path('', views.IndexView.as_view(), name='index'),
        path('<int:pk>/', views.DetailView.as_view(), name='detail'),
        path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
        path('<int:question_id>/vote/', views.vote, name='vote'),
    ]
    
    
    

    10、django给我们每一个app提供了静态资源的管理,创建<app name>/static/<app name>/style.css


    image.png

    index.html引用样式

    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
    
    image.png

    相关文章

      网友评论

        本文标题:django搭建web网站

        本文链接:https://www.haomeiwen.com/subject/tgngnhtx.html