Django零基础(四)


前言

Windows下利用Django框架进行Web应用开发
Python三剑客第一本踩坑,学习笔记接上一节
如果寻找错误解决办法可以直接跳到总结查看错误类型再查看相应小节即可


一、设置学习笔记的样式

在前面的学习中我们已经完成了学习笔记的基本功能,这节我们使用Bootstrap库来设置其样式

1.安装库Django-bootstrap3

(p_env) ...\practice>pip install django-bootstrap3

若报错:ValueError: check_hostname requires server_hostname,则把VPN代理或梯子关掉,再次安装

成功下载好之后打开settings.py将bootstrap3应用程序包含进项目中
在这里插入图片描述
接下来我们让django-bootstrap3包含jQuery,这是一个JavaScript库,让你能够使用Bootstrap模板提供的交互元素
在settings.py末尾添加如下代码:

# django-bootstrap3的设置
BOOTSTRAP3 = {
    'include_jquery': True,
    }

在这里插入图片描述

2.使用Bootstrap库

接下来我们使用Bootstrap的Static top navbar模板来为网页设置样式

2.1 修改base.html

我们首先对base.html页面套用模板,打开它删除所有代码,添加新代码如下:

{% load bootstrap3 %}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Learning Log</title>

        {% bootstrap_css %}
        {% bootstrap_javascript %}

    </head>

    <body>

        <!-- Static navbar -->
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">

                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed"
                            data-toggle="collapse" data-target="#navbar"
                            aria-expanded="false" aria-controls="navbar">
                    </button>
                    <a class="navbar-brand" hred="{% url 'learning_logs:index' %}">
                        Learning Log
                    </a>
                </div>

                <div id="navbar" class="navbar-collapse collapse">
                    <ul class="navbar navbar-nav">
                        <li><a href="{% url 'learning_logs:topics' %}">Topics</a></li>
                    </ul>

                    <ul class="navbar navbar-nav navbar-right">
                        {% if user.is_authenticated %}
                        <li><a>Hello, {{ user.username }}.</a></li>
                        <li><a href="{% url 'users:logout' %}">log out</a></li>
                        {% else %}
                        <li><a href="{% url 'users:register' %}">register</a></li>
                        <li><a href="{% url 'users:login' %}">log in</a></li>
                        {% endif %}
                    </ul>
                </div><!--/.nav-collapse -->
            </div>
        </nav>

        <div class="container">

            <div class="page-header">
                {% block header %}{% endblock header %}
            </div>
            <div>
                {% block content %}{% endblock content %}
            </div>
        </div><!-- /container -->

    </body>
</html>

保存之后启动网络服务,进入页面观察效果
在这里插入图片描述

2.2 修改主页样式

可以看到页面有瑕疵,接下来使用jumbotron来设置主页的样式,打开index.html,修改如下:

{% extends "learning_logs/base.html" %}

{% block header %}
<div class="jumbotron">
    <h1>Track your learning.</h1>
</div>
{% endblock header %}

{% block content %}
<h2>
    <a href="{% url 'users:register' %}">Register an account</a> to make
    your own Learning Log, and list the topics you're learning about.
</h2>
<h2>
    Whenever you learn something new about a topic, make an entry
    summarizing what you've learned.
</h2>

{% endblock content %}

在这里插入图片描述
可以看到左右按钮还是不太对,返回到base.html检查发现问题所在,修改代码34和38行,把navbar改成nav

<ul class="nav navbar-nav">
   <li><a href="{% url 'learning_logs:topics' %}">Topics</a></li>
   </ul>
<ul class="nav navbar-nav navbar-right">

在这里插入图片描述
OK,页面可以正常显示了。

2.3 改进登录页面

打开login.html,修改代码如下:

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
<h2>
    Log in to your account.
</h2>
{% endblock header %}

{% block content %}

  <form method="post" action="{% url 'users:login' %}" class="form">
      {% csrf_token %}
      {% bootstrap_form form %}

      {% buttons %}
      <button name="submit" class="btn btn-primary">log in</button>
      {% endbuttons %}

      <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
  </form>  
{% endblock content %}

至此我们已经有一个比较简洁的页面了
在这里插入图片描述

3.修改其他网页使其风格一致

方法与2.3类似,打开new_topic.html并修改如下:

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
<h2>
    Add a new topic:.
</h2>
{% endblock header %}

{% block content %}

<form action="{% url 'learning_logs:new_topic' %}" method="post" class="form">
    {% csrf_token %}
    {% bootstrap_form form %}

    {% buttons %}
    <button name="submit" class="btn btn-primary">add topic</button>
    {% endbuttons %}

</form>

{% endblock content %}

打开topics.html,修改如下:

{% extends "learning_logs/base.html" %}

{% block header %}
<h2>
    Topics
</h2>
{% endblock header %}

{% block content %}

<ul>
    {% for topic in topics %}
    <li>    
        <h3>
            <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
        </h3>
    </li>
    {% empty %}
    <li>No topics have been added yet.</li>
    {% endfor %}
</ul>

<h3><a href="{% url 'learning_logs:new_topic' %}">Add new topic</a></h3>

{% endblock content %}

打开topic.html,使用Bootstrap面板来突出每个条目,修改代码如下:

{% extends 'learning_logs/base.html' %}

{% block header %}
<h2>
    {{ topic }}
</h2>
{% endblock header %}

{% block content %}

<p>
    <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
</p>

{% for entry in entries %}
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3>
                {{ entry.date_added|date:'M d, Y H:i' }}
                <small>
                    <a href="{% url 'learning_logs:edit_entry' entry.id %}">
                        edit entry
                    </a>
                </small>
            </h3>
        </div>
        <div class="panel-body">
            {{ entry.text|linebreaks }}
        </div>
    </div><!-- panel -->
    {% empty %}
        There are no entries for this topic yet
    {% endfor %}


{% endblock content %}

在这里插入图片描述
练习:对注册页面,new_entry页面和edit_entry进行修改,可以自行修改后观看效果
先修改new_entry,修改代码如下:

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
<h2>
    Add a new entry:
</h2>
{% endblock header %}

{% block content %}

<h3>
    <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</h3>


<form action="{% url 'learning_logs:new_entry' topic.id %}" method="post" class="form">
    {% csrf_token %}
    {% bootstrap_form form %}

    {% buttons %}
    <button name="submit" class="btn btn-primary">add entry</button>
    {% endbuttons %}
</form>

{% endblock content %}

再修改edit_entry,代码如下:

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
<h2>
    Edit entry:
</h2>
{% endblock header %}

{% block content %}

<h3>
    <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</h3>


<form action="{% url 'learning_logs:edit_entry' entry.id %}" method="post" class="form">
    {% csrf_token %}
    {% bootstrap_form form %}

    {% buttons %}
    <button name="submit" class="btn btn-primary">save changes</button>
    {% endbuttons %}
</form>

{% endblock content %}

修改注册页面,代码如下:

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
<h2>
    Register your account:
</h2>
{% endblock header %}


{% block content %}

<form method="post" action="{% url 'users:register' %}" class="form">
    {% csrf_token %}
    {% bootstrap_form form %}

    {% buttons %}
    <button name="submit" class="btn btn-primary">register</button>
    {% endbuttons %}

    <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>

{% endblock content %}

方法都类似,读者可以自行尝试,修改后我们网页的每个页面都风格一致

在这里插入图片描述

二、部署网页到服务器中

1.使用Heroku平台部署应用程序

我们首先访问https://heroku.com/注册一个账户,注册时候不能使用163和qq邮箱
接下来访问https://toolbelt.heroku.com/,安装最新的Heroku Toolbelt版本
还需要安装一些必要的包以便在服务器上支持Django项目提供的服务

(p_env) ...\practice>pip install dj-database-url
(p_env) ...\practice>pip install dj-static
(p_env) ...\practice>pip install gunicorn

因为static3在新版本中包含在dj-static中,因此无需再使用pip命令安装
dj-database-url帮助Django与Heroku使用的数据库通信,dj-static帮助Django正确地管理静态文件,而gunicorn是一个服务器软件,能够在在线环境中支持应用程序提供的服务。(静态文件包括样式规则和JavaScript文件)

创建包含包列表的文件requirements.txt,Heroku需要知道我们的项目依赖于哪些包,因此我们将使用pip来生成一个文件,其中列出我们所使用到的包,可以看到生成文件成功,里面包含该虚拟环境下的包

(p_env) ...\practice>pip freeze > requirements.txt

在这里插入图片描述
我们部署“学习笔记”时,Heroku将按照requirements.txt列出的所有包,因此项目部署到Heroku后将与本地系统上的完全相同

接下来我们在requirements.txt中添加包psycopg2,它帮助Heroku管理活动数据库。打开文件,添加代码行psycopg2>=2.6.1,如果没有更高版本,这将安装2.6.1版的psycopg2

接下来我们需要在Heroku中指定python版本,先看看本地python版本是多少

(p_env) ...\practice>python --version

在目录下新建一个runtime.txt文件,添加版本号
在这里插入图片描述
接下来打开settings.py在末尾添加一个片段指定一些Heroku环境设置:

# Heroku设置
cwd = os.getcwd()
if cwd == '/app' or cwd[:4] == '/tmp':
    import dj_database_url
    DATABASES = {
        'default': dj_database_url.config(default='postgres://localhost')
        }

    # 让request.is_secure()承认X-Forwarded-Proto头
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

    # 支持所有的主机头(host header)
    ALLOWED_HOSTS = ['*']

    # 静态资产配置
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    STATIC_ROOT = 'staticfiles'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
        )

我们使用getcwd()来获取当前的工作目录,这个if测试确保仅当项目被部署到Heroku中时才运行这个代码,我们导入了dj_database_url用于在Heroku上配置服务器。Heroku使用PostgreSQL(一种比SQLite更高级的数据库);这些设置对项目进行配置使其在Heroku上使用Postgres数据库。其他设置作用如下,支持HTTPS请求;让Django能够使用Heroku的URL来提供项目提供的服务;设置项目,使其能够在Heroku上正确地提供静态文件。

接着我们创建启动进程Procfile,Procfile告诉Heroku启动哪些进程以便能够正确地提供项目提供的服务,不指定文件扩展名
在这里插入图片描述
在这里插入图片描述

这行代码让Heroku将gunicorn用作服务器,并使用practice_p/wsgi.py中的设置来启动程序,标志log-file告诉Heroku应将哪些类型事件写入日志

为部署到Heroku我们还需修改wsgi.py,修改如下:

import os

from django.core.wsgi import get_wsgi_application
from dj_static import Cling

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'practice_p.settings')

application = Cling(get_wsgi_application())

创建用于存储静态文件的目录static,添加占位文件placeholder.txt
在这里插入图片描述
由于Windows不能本地使用gunicorn服务器,因此我们直接下一步
配置Git跟踪项目文件并提交项目,具体操作见书
先安装Git,命令git --version查看版本
配置Git,提供用户名和邮箱,命令git config --global user.name “example”;git config --global user.email “ddd@exa.com”
在manage.py目录下创建.gitgnore文件,无扩展名。添加忽略路径p_env/;pycache/;*.sqlite3(分号为换行)
提交项目,命令git init;git add .;git commit -am “Ready for deployment to heroku.”;git status
如果提示,warning: LF will be replaced by CRLF in … 运行git config --global core.autocrlf true即可

接下来我们终于可以将项目推送到Heroku中了
执行命令heroku login -i,使用之前注册的邮箱登录
在这里插入图片描述
再执行create命令创建一个空项目
继续命令git push heroku master,报错
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/

查找众多资料后错误无法解决。。。
仔细观察代码发现python版本不对,runtime中我们改成3.6.14版本

打开settings.py,添加import os!!!!!!!
啊啊啊,查找半天之后终于解决了,说一下解决步骤
修改好settings.py后,删掉文件夹的.git文件重新配置一遍,再跟着步骤走就行
在这里插入图片描述
分支切换可以参考上图,不过我们用不到一个重点是heroku git:remote -a your_appname,使用这条命令将git部署到我们创建的程序中

接下来我们使用heroku ps命令核实正确的启动了服务器,可以看到显示和书中不同
在这里插入图片描述
使用命令heroku open打开网页我们可以看到
在这里插入图片描述
应该是我们还没有在heroku上部署该程序的问题,我们先建立数据库再回来部署

2.建立数据库

为建立在线数据库,我们需要再次执行命令migrate,并应用在开发期间生成的所有迁移
执行命令

(p_env) ...\practice>heroku run python manage.py migrate

再看了一下还是Application error
An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details. You can do this from the Heroku CLI with the command.
好像这个错误不是heroku的原因,再找找看,感觉是Procfile的问题

git push的时候,如果出现报错"Everything up-to-date"
再次执行git add . 和git commit -am “提交信息”

试了一下果然是Procfile的问题,在web:后面一定要加一个空格,如果不加就不能进行web服务,修改Procfile后执行上面命令,重新上传git库,再次打开网页可以看到我们已经部署到服务器中了
在这里插入图片描述
试着登录了一下发现并没有本地上的数据信息,接下来我们进一步改进它的部署

3.改进Heroku部署

3.1 创建超级用户

我们执行命令

(p_env) ...\practice>heroku run bash

来打开一个远程的Bash终端会话,它是Linux的,我们通过它来创建超级用户
在这里插入图片描述
创建过程和第二讲一样,有兴趣可以点击主页查看,按步骤操作即可

3.2 创建用户友好URL

我们可以使用heroku apps:rename learning-log命令来重命名我们的应用程序,给应用程序命名可以使用字母,数字和连字符,learning-log显然被命名过,我们可以自定义自己的应用程序名字,现在项目的URL变成了https://learning-log.herokuapp.com/,使用以前的URL无法访问它,登录网站后发现好像和我们开发的有点不一样,应该是版本更新之后改了页面格式,我用的是第一版。
在这里插入图片描述

3.3 确保项目的安全

打开我们的settings.py看到第26行可以看到DEBUG=True,这使得用户访问错误页面时将显示调试信息,这将会给攻击者提供大量可供利用的信息,我们还需确保任何人都无法看到这些信息,也不能冒充项目托管网站来重定向请求,下面来修改settings.py

    # 只允许Heroku托管这个项目
    ALLOWED_HOSTS = ['learning-log.herokuapp.com']

    DEBUG = False

在这里插入图片描述
提交修改并推送到heroku中
在这里插入图片描述
在这里插入图片描述

3.4 创建自定义错误界面

创建自定义模板,在practice\practice_p中新建templates文件夹,新建404.html文件,添加代码:

{% extends "learning_logs/base.html" %}

{% block header %}
<h2>
    The item you requested is not available.(404)
</h2>

新建500.html文件,添加代码:

{% extends "learning_logs/base.html" %}

{% block header %}
<h2>
    There has been an internal error.(500)
</h2>

修改settings.py,在TEMPLATES中添加路径
在这里插入图片描述
保存,将项目推送到heroku,需先执行git add .命令,其他和上面一样
在这里插入图片描述
记得把import os放在最开头,修改之后按步骤推送就行了
最后我们使用方法get_boject_or_404()来判定用户手工请求不存在的主题与条目
打开views.py,修改这两行代码如下:

from django.shortcuts import render, get_object_or_404
    topic = get_object_or_404(Topic, id = topic_id)

这时如果我们请求不存在的主题或条目将显示404错误,再次将其推送到heroku中。

至此我们的Django项目开发结束,读者可以试着进一步开发自己的功能与操作。


总结

一定一定一定要仔细看错误代码,百度有时候并不能完全解决问题,看代码定位到问题才能对症下药!!!

再总结一下部署不成功时该怎样操作,报错
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/
时请先检查python版本是否支持heroku栈,可以登录 https://devcenter.heroku.com/articles/python-support查看离自己版本最近的python版本,在runtime.txt中修改它

报错NameError: name ‘os’ is not defined时在settings.py中添加import os,接下来把项目文件中的.git文件夹删掉重新操作一遍。运行git add .命令时出现warning: LF will be replaced by CRLF错误则运行
git config --global core.autocrlf true,再运行git add .命令,(我之后又运行了git config --global core.autocrlf false还原环境,不知道对提交项目有无影响,如果部署不成功可以回到这步试试)

接下来就是登录,切换APP路径,部署git文件啦,按书上操作走就可以,或者回到上面查看具体步骤
报错fatal: ‘heroku’ does not appear to be a git repository时执行heroku git:remote -a your_appname命令,打开heroku网页进入自己应用程序的Deploy模块也能看到,实操便知

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值