python编程从入门到实践——Web应用程序(第18-20章不包含部署Heroku)

emmmmm 一段时间没上来了,这个几个章节之前已经over 但是我电脑布Heroku老是有问题heroku login404 郁闷了有空再研究,先搁置打个疑问,单说学习笔记这个项目,多有不足仅供学习参考,欢迎指点。

内容:

Learning Log 是本次要开发的一个日志系统。django web框架帮助开发交互式的网站,响应网页的请求,读取管理用户等。主要记录django 的安装,应用程序的创建、网页的创建、账户创建、数据约束、页面样式设定等。

  1. django安装:安装过程遇到一些杂七杂八的问题,但是不打算放过这些,所以都记录下来了。
  2. 应用程序的创建:定义模型
  3. 创建网页:HTML新手,表示可以接受好理解,包括映射URL、视图模板页面的编写。
  4. 账户的创建、数据的约束:分admin 和普通user 用户各自的数据要进行约束保护,数据的独立。
  5. 样式设定:这里运用了django-bootstrap3 程序规范美化页面。

必须提一下版本,由于自用版本比书里的高 语法等会有不一样的:
pycharm 2019 2.2
python 3.7.3
Django 2.2.5
Windows 10

django 安装

我喜欢用 windows powershell敲(也许有人喜欢 cmd or linux等 此可能不适用emmm)
如果假设打开powershell困扰(良心推荐2步):
找到你安装python的地方,如果不记得了可以桌面右键属性找到位置按住shift键右键
在这里插入图片描述
在这里插入图片描述
OK!

安装Django

计算机默认执行策略对于修改是不允许,需要改下,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
cd .\learning_log
get-executionpolicy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
get-executionpolicy
ll_env/Scripts/activate(我们用的虚拟环境,所以需要先激活)

创建项目

django-admin startproject learning_log_lx .
dir
在这里插入图片描述
python manage.py runserver 后进浏览器查看http://127.0.0.1:8000/
在这里插入图片描述安装成功

创建应用程序

在这里插入图片描述
这里先贴图显示修改数据库需要做的
Django修改数据库,能存储与topic(我们刚创的)的信息
python manage.py makemigrations learning_logs
python manage.py migrate
在这里插入图片描述
总之,修改数据后 需要进行3步骤: 修改models.py——>对learning_logs调用makemigrations——>让Django迁移项目。
python manage.py migrate
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后台调试
在这里插入图片描述

>>> from learning_logs.models import Topic
>>> Topic.objects.all()
<QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]>
>>> topics = Topic.objects.all()
>>> for topic in topics:
...     print(topic)
...
Chess
Rock Climbing
>>> t =Topic.objects.get(id=1)
>>> t.text
'Chess'
>>> t.date_added
datetime.datetime(2019, 9, 9, 9, 15, 0, 867771, tzinfo=<UTC>)
>>>
>>>
>>> t.entry_set.all()
<QuerySet [<Entry: The chess rules approved by the "International Che...>, <Entry: Chess games are played by both sides moving their ...>]

创建用户账户
Python manage.py startapp users
在这里插入图片描述

目录结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

代码较杂 打包了 这里部分出来
setting.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 第三方应用程序
    'bootstrap3',
    # my apps
    'learning_logs',
    'users',
]
*--snip--*
# 我的设置
LOGIN_URL = '/users/login/'
# django-bootstrap3的设置
BOOTSTRAP3 = {
    'include_jquery': True,
}

# 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-Fordwarded-Proto头
    SECURE_PROXY_SSL_HEARDER = ('HTTP_X_FORDWARDED_PROTO', 'https')

    # 支持所有的主机头
    ALLOWED_HOSTS = ['*']

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

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),
    # 可能版本不一样按照书里的有问题,include() 第一个参数得是元组带app_name
    path('users/',
         include(('users.urls', 'users'), namespace='users')),
    path('', include(
        ('learning_logs.urls', 'learning_logs'), namespace='learning_logs')),

]

wsgi.py

import os

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


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

application = Cling(get_wsgi_application())

learning_logs下
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" href="{% url 'learning_logs:index' %}">
                    Learning Log</a>
            </div>

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

                <ul class="nav 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>

topic.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" href="{% url 'learning_logs:index' %}">
                    Learning Log</a>
            </div>

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

                <ul class="nav 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>

edit_entry.html

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

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


{% block content %}
    <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
    <form action="{% url 'learning_logs:edit_entry' entry.id %}" method="post"
          class="form">
        {% csrf_token %}
        {% bootstrap_form form %}

        {% buttons %}
        <button name="submit">save changes</button>
        {% endbuttons %}
    </form>
{% endblock content %}

admin.py

from django.contrib import admin

# 向管理网站注册Topic,这时可以通过django在网页管理
from learning_logs.models import Topic, Entry

admin.site.register(Topic)
admin.site.register(Entry)

urls.py

"""定义learning_logs 的URL模式"""
from django.urls import path

from . import views  # 从当前的文件夹导入

urlpatterns = [
    # 主页
    path('', views.index, name='index'),  # r'^$'正则表示将字符串头尾检查

    # 显示所有主题
    path('topics/', views.topics, name='topics'),

    # 特定主题的详细信息
    path('topics/<int:topic_id>/', views.topic, name='topic'),

    # 用于添加新主题的网页
    path(r'new_topic/', views.new_topic, name='new_topic'),

    # 用于添加新条目的页面
    path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),

    # 用于编辑条目的页面
    path('edit_entry/<int:entry_id>/', views.edit_entry, name='edit_entry')

    ]

views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect, Http404
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from .models import Topic, Entry
from .forms import TopicForm, EntryForm


# Create your views here.
def index(request):
    """学习笔记的主页"""
    return render(request, 'learning_logs/index.html')


@login_required
def topics(request):
    """显示所有主题"""
    topics = Topic.objects.filter(owner=request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)


@login_required
def topic(request, topic_id):
    """显示所有主题机及其所有条目"""
    topic = Topic.objects.get(id=topic_id)
    # 确认请求的主题属于当前用户
    check_topic_owner(topic, request)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)


def check_topic_owner(topic, request):
    """核实主题关联的任务的当前用户"""
    if topic.owner != request.user:
        raise Http404


@login_required
def new_topic(request):
    """添加新主题"""
    if request.method != 'POST':
        # 未提交数据:创建一个新表单
        form = TopicForm()

    else:
        # POST提交的数据,对数据进行处理
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))

    context = {'form': form}
    return render(request, 'learning_logs/new_topic.html', context)


@login_required
def new_entry(request, topic_id):
    """在特定的主题中添加新条目"""
    topic = Topic.objects.get(id=topic_id)

    if request.method != 'POST':
        # 未提交数据, 创建一个新表单
        form = EntryForm()
    else:
        # POST提交数据, 并对数据进行处理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            # 将新主题关联到当前用户
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            # new_entry.topic.owner = request.user
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                                args=[topic_id]))
    context = {'topic': topic, 'form': form}
    return render(request, 'learning_logs/new_entry.html', context)


@login_required
def edit_entry(request, entry_id):
    """编辑现有条目"""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic
    # 确认请求的主题属于当前用户
    check_topic_owner(topic, request)

    if request.method != 'POST':
        # 初次请求,使用当前条目填充表单
        form = EntryForm(instance=entry)
    else:
        # POST提交数据,对数据进行处理
        form = EntryForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                                args=[topic.id]))
    context = {'entry': entry, 'topic': topic, 'form': form}
    return render(request, 'learning_logs/edit_entry.html', context)

user目录
urls.py

"""为应用程序定义URL模式"""
from django.urls import path
from django.contrib.auth.views import LoginView
from . import views

urlpatterns = [
    # 登录页面
    path('login/', LoginView.as_view(template_name='users/login.html'),
         name='login'),
    path('logout/', views.logout_view, name='logout'),
    # 注册页面
    path('register/', views.register, name='register'),
]

views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm


def logout_view(request):
    """注销用户"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))


def register(request):
    """注册新用户"""
    if request.method != 'POST':
        # 显示空的注册表单
        form = UserCreationForm()
    else:
        form = UserCreationForm(data=request.POST)
        # 处理已经写好的表单
        if form.is_valid():
            new_user = form.save()
            # 让用户自动登录再重定向到页面
            authenticated_user = authenticate(
                username=new_user.username, password=request.POST['password1'])
            login(request, authenticated_user)
            return HttpResponseRedirect(reverse('learning_logs:index'))
    context = {'form': form}
    return render(request, 'users/register.html', context)

代码粘贴不全 具体见打包

django官方文档

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值