IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python从入门到实践19章答案 -> 正文阅读

[Python知识库]python从入门到实践19章答案

目录

前言

一、博客

1.建立项目

2.创建应用程序

3.Django管理网站

?4.让用户输入数据

二、博客账户

1.应用程序users

2.登录页面

3.注销

4.注册页面

三、重构

四、保护页面new_entry

五、受保护的博客

1.使用@login_required限制访问

2.将数据关联到用户

3.保护页面


前言

这里是《Python从入门到实践》的练习答案,如果有错误或者可以改进的地方欢迎在评论区指正


一、博客

1.建立项目

每次新建项目时操作都相似:

建立虚拟环境

激活虚拟环境

安装django

在django中创建项目

创建数据库

这一部分操作与第18章基本相同

终端:?

PS Blog> python -m venv Blog_env
PS Blog> cd C:\softwaregongjv\Python\python_codes\Blog\Blog_env\Scripts
PS Blog\Blog_env\Scripts> .\activate
(Blog_env) PS Blog\Blog_env\Scripts> cd Blog

(Blog_env) PS Blog> pip install django
Collecting django
  Using cached Django-4.0.6-py3-none-any.whl (8.0 MB)
Collecting tzdata
  Using cached tzdata-2022.1-py2.py3-none-any.whl (339 kB)
--snip--
Installing collected packages: tzdata, sqlparse, asgiref, django
Successfully installed asgiref-3.5.2 django-4.0.6 sqlparse-0.4.2 tzdata-2022.1
(Blog_env) PS Blog> django-admin startproject Blog .
(Blog_env) PS Blog> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  --snip--
(Blog_env) PS Blog>

2.创建应用程序

终端

(Blog_env) PS Blog> python manage.py startapp blogs

定义模型 Blog\blogs\models.py

from django.db import models

class BlogPost(models.Model):
    """a model of Blog page"""
    title = models.CharField(max_length=200)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        # display simple information about the model
        # return a string representation of the model
        return self.title +'=='+ self.text

激活模型 Blog\Blog\settings.py

# Application definition

INSTALLED_APPS = [
    # my apps
    'blogs',

    # the default applications
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

终端

(Blog_env) PS Blog> python manage.py makemigrations blogs
Migrations for 'blogs':
  blogs\migrations\0001_initial.py
    - Create model BlogPost
(Blog_env) PS Blog> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, blogs, contenttypes, sessions
Running migrations:
  Applying blogs.0001_initial... OK
(Blog_env) PS Blog>

3.Django管理网站

创建超级用户 终端

(Blog_env) PS Blog> python manage.py createsuperuser
Username (leave blank to use '--snip--'): 11-admin
Email address:
Password:
Password (again):
Superuser created successfully.
(Blog_env) PS Blog>

向管理网站注册模型 Blog\blogs\admin.py

from django.contrib import admin

from .models import BlogPost

admin.site.register(BlogPost)

使用管理网站创建几个简短的帖子,效果如下:

?4.让用户输入数据

这一步我借鉴了另一篇文章的答案,并略作修改,原文在此:

白桃提拉米苏的答案

表单 新建?Blog\blogs\forms.py

from django import forms

from .models import BlogPost

class BlogPostForm(forms.ModelForm):
	class Meta:
		model = BlogPost
		fields = ['title','text']  # 获取模型里的两个字段
		widgets = {'text': forms.Textarea(attrs={'cols':80})}

视图 Blog\blogs\views.py

from django.shortcuts import render,redirect

from .models import BlogPost

from .forms import BlogPostForm

def index(request):
	""" 主页,显示所有 """
	blogposts = BlogPost.objects.order_by('-date_added')
	context = {'blogposts':blogposts}
	return render(request,'blogs/index.html',context)

def new_blog(request):
	""" 添加新博客 """
	if request.method != 'POST':
		form = BlogPostForm()
	else:
		form = BlogPostForm(data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('blogs:index')
	context = {'form':form}
	return render(request,'blogs/new_blog.html',context)

def edit_blog(request,blog_id):
	""" 编辑博客 """
	blogpost = BlogPost.objects.get(id=blog_id)
	title = blogpost.title

	if request.method != 'POST':
		form = BlogPostForm(instance=blogpost)
	else:
		form = BlogPostForm(instance=blogpost,data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('blogs:index')
	context = {'blogpost':blogpost,'title':title,'form':form}
	return render(request,'blogs/edit_blog.html',context)

URL模式

Blog\Blog\urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blogs.urls')),
]

?Blog\Blogs\urls.py

from django.urls import path

from . import views

app_name = 'blogs'

urlpatterns = [
	path('',views.index,name='index'),
	path('new_blog/',views.new_blog,name='new_blog'),
	path('edit_blog/<int:blog_id>/',views.edit_blog,name='edit_blog'),
]

以下是所有html文件 路径 Blog\blogs\templates\blogs\--snip--.html

base.html

<p>
	<a href="{% url 'blogs:index' %}">BLOG</a> -
	<a href="{% url 'blogs:new_blog' %}">Add new blog</a>
</p>

{% block content %}{% endblock content%}

index.html

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

{%block content%}
  <p><h1>Blog 主页</h1></p>
  <ul>
  {%for blogpost in blogposts%}
    <li>
      <p>{{ blogpost.date_added|date:'Y m d, H:i' }}</p>
    </li>
    <p><h4>{{blogpost.title}}</h4></p>
    <p>{{blogpost|linebreaks}}</p>
    <a href="{%url 'blogs:edit_blog' blogpost.id%}">Edit Blog</a>
  {%empty%}
    <p>No blogs have been added.</p>
  {%endfor%}
  </ul>
  
{%endblock content%}

new_blog.html

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

{%block content%}
	<p><h2>Add A New Blog</h2></p>
	<form action="{% url 'blogs:new_blog'%}" method="post">
		{% csrf_token %}
		{{ form.as_p }}
		<button  name="submit">Add Blog</button>
	</form>

{%endblock content%}

edit_blog.html

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

{%block content%}
	<p>{{ title }}</p>
	<form action="{% url 'blogs:edit_blog' blogpost.id %}" method="post">
		{% csrf_token %}
		{{ form.as_p }}
		<button  name="submit">Save changes</button>
	</form>

{%endblock content%}

效果:


二、博客账户

1.应用程序users

创建一个名为users的应用程序?终端

(Blog_env) PS Blog> python manage.py startapp users
(Blog_env) PS Blog> dir


    目录: Blog


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2022/7/28     18:28                Blog
d-----         2022/7/29     16:44                blogs
d-----         2022/7/28     18:24                Blog_env
d-----         2022/7/30      9:56                users
-a----         2022/7/29     13:47         135168 db.sqlite3
-a----         2022/7/28     18:27            682 manage.py


(Blog_env) PS Blog>

将users添加到settings.py中 Blog\Blog\settings.py

# Application definition

INSTALLED_APPS = [
    # my apps
    'blogs',
    'users',

    # the default applications
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

包含users的URL?Blog\Blog\urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('blogs.urls')),
    path('users/',include('users.urls')),
]

2.登录页面

新建?Blog\users\urls.py

"""define the URL pattern for the Users application"""

from django.urls import path, include

app_name = 'users'
urlpatterns = [
    # contain the default authentication URL
    path('', include('django.contrib.auth.urls')),
]

模板login.html 新建 Blog\users\templates\registration\login.html

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

{% block content %}

  {% if form.errors %}
    <p>Your username and password didn't match.Please try again.</p>
  {% endif %}

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

    <button name="submit">Log in</button>
    <input type="hidden" name="next"
      value="{% url 'blogs:index' %}" />
  </form>

{% endblock content %}

在base.html中添加到登陆页面的链接?

<p>
	<a href="{% url 'blogs:index' %}">BLOG</a> -
	<a href="{% url 'blogs:new_blog' %}">Add new blog</a> -
	{% if user.is_authenticated %}
	 Hello, {{ user.username }}.
	{% else %}
	  <a href="{% url 'users:login' %}">Log in</a>
	{% endif %}
</p>

{% block content %}{% endblock content%}

3.注销

现在需要向用户提交一个注销的途径

在 base.html中添加注销链接 Blog\blogs\templates\blogs\base.html

<p>
	<a href="{% url 'blogs:index' %}">BLOG</a> -
	<a href="{% url 'blogs:new_blog' %}">Add new blog</a> -
	{% if user.is_authenticated %}
	 Hello, {{ user.username }}. -
	 <a href="{% url 'users:logout' %}">Log out</a>
	{% else %}
	  <a href="{% url 'users:login' %}">Log in</a>
	{% endif %}
</p>

{% block content %}{% endblock content%}

注销确认页面 新建Blog\users\templates\registration\logged_out.html

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

{% block content %}

  <p>You have been logged out.Thank you for visiting!</p>

{% endblock content %}

效果:

?

?

4.注册页面

注册页面的URL模式?

"""define the URL pattern for the Users application"""

from django.urls import path, include

from . import views

app_name = 'users'
urlpatterns = [
    # contain the default authentication URL
    path('', include('django.contrib.auth.urls')),
    # register page
    path('register/', views.register, name='register'),
]

注册页面的视图函数 Blog\users\views.py

from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm

def register(request):
    """register a new user"""
    if request.method != 'POST':
        # display an empty registration form
        form = UserCreationForm()
    else:
        # process completed forms
        form = UserCreationForm(data=request.POST)

        if form.is_valid():
            new_user = form.save()
            # let the user log in automatically and
            # redirect to the home page

            login(request, new_user)
            return redirect('blogs:index')

    # display an empty form and indicate that the form is invalid
    context = {'form': form}
    return render(request, 'registration/register.html', context)

注册页面的模板 Blog\users\templates\registration\register.html

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

{% block content %}

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

    <button name="submit">Register</button>
    <input type="hidden" name="next" value="{% url 'blogs:index' %}" />
  </form>

{% endblock content %}

修改base.html

<p>
	<a href="{% url 'blogs:index' %}">BLOG</a> - 
	<a href="{% url 'blogs:new_blog' %}">Add new blog</a> - 
	{% if user.is_authenticated %}
	 Hello, {{ user.username }}. - 
	 <a href="{% url 'users:logout' %}">Log out</a>
	{% else %}
	  <a href="{% url 'users:register' %}">Register</a> -
	  <a href="{% url 'users:login' %}">Log in</a>
	{% endif %}
</p>

{% block content %}{% endblock content%}


三、重构

注意: 3、4题是对learning_log项目进行修改

修改书中的项目 learning_log\learning_logs\views.py

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.http import Http404

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)

@login_required
def new_topic(request):
    """添加新主题"""
    if request.method != 'POST':
        # 未提交数据:创建一个新表单
        form = TopicForm()
    else:
        # POST 提交的数据:对数据进行处理
        form = TopicForm(data=request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            return redirect('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.save()
            return redirect('learning_logs:topic', topic_id=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 redirect('learning_logs:topic', topic_id=topic.id)
        
    context = {'entry': entry, 'topic': topic, 'form': form}
    return render(request, 'learning_logs/edit_entry.html', context)

def check_topic_owner(topic, request):
    # 确认请求的主题属于当前用户
    if topic.owner != request.user:
        raise Http404

效果:


四、保护页面new_entry

?

修改书中的项目 learning_log\learning_logs\views.py

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

    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.save()
            return redirect('learning_logs:topic', topic_id=topic_id)
    
    # 显示空表单或指出表单数据无效
    context = {'topic': topic, 'form': form}
    return render(request, 'learning_logs/new_entry.html', context)

效果:

?


五、受保护的博客

? ? ? ? 我们将创建一个系统,确定各项博文所属的用户。已登录用户能发表、修改自己的博文,任何用户都能访问所有博文

1.使用@login_required限制访问

Blog\blogs\views.py

from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required

from .models import BlogPost

from .forms import BlogPostForm

def index(request):
	""" 主页,显示所有 """
	blogposts = BlogPost.objects.order_by('-date_added')
	context = {'blogposts':blogposts}
	return render(request,'blogs/index.html',context)

@login_required
def new_blog(request):
	""" 添加新博客 """
	if request.method != 'POST':
		form = BlogPostForm()
	else:
		form = BlogPostForm(data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('blogs:index')
	context = {'form':form}
	return render(request,'blogs/new_blog.html',context)

@login_required
def edit_blog(request,blog_id):
	""" 编辑博客 """
	blogpost = BlogPost.objects.get(id=blog_id)
	title = blogpost.title

	if request.method != 'POST':
		form = BlogPostForm(instance=blogpost)
	else:
		form = BlogPostForm(instance=blogpost,data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('blogs:index')
	context = {'blogpost':blogpost,'title':title,'form':form}
	return render(request,'blogs/edit_blog.html',context)

在Blog\Blog\settings.py末尾添加

# my settings
LOGIN_URL = 'users:login'

2.将数据关联到用户

修改模型BlogPost? ?Blog\blogs\models.py

from django.db import models
from django.contrib.auth.models import User

class BlogPost(models.Model):
    """a model of Blog page"""
    title = models.CharField(max_length=200)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    owner = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        # display simple information about the model
        # return a string representation of the model
        return self.text

迁移数据库 终端

(Blog_env) PS Blog> python manage.py shell
>>> from django.contrib.auth.models import User
>>> User.objects.all()
<QuerySet [<User: 11-admin>]>
>>> for user in User.objects.all():
...     print(user.username, user.id)
...
11-admin 1
>>> exit()
(Blog_env) PS Blog> python manage.py makemigrations blogs
Select an option:1
>>> 1
(Blog_env) PS Blog> python manage.py migrate
(Blog_env) PS Blog> python manage.py shell
>>> from blogs.models import BlogPost
>>> for blog in BlogPost.objects.all():
...     print(blog.title, blog.owner)
...
账单同 11-admin
徐梓蕊 11-admin
--snip--
>>> exit()
(Blog_env) PS Blog>

3.保护页面

edit_blog 修改?Blog\blogs\views.py 的部分方法

@login_required
def edit_blog(request,blog_id):
	""" 编辑博客 """
	blogpost = BlogPost.objects.get(id=blog_id)
	title = blogpost.title
	# protect the page
	if blogpost.owner != request.user:
		raise Http404

	if request.method != 'POST':
		form = BlogPostForm(instance=blogpost)
	else:
		form = BlogPostForm(instance=blogpost,data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('blogs:index')
	context = {'blogpost':blogpost,'title':title,'form':form}
	return render(request,'blogs/edit_blog.html',context)

将新主题关联到当前用户?修改?Blog\blogs\views.py 的部分方法

@login_required
def new_blog(request):
	""" 添加新博客 """
	if request.method != 'POST':
		form = BlogPostForm()
	else:
		form = BlogPostForm(data=request.POST)
		if form.is_valid():
			new_blog = form.save(commit=False)
			new_blog.owner = request.user
			new_blog.save()
			return redirect('blogs:index')
	context = {'form':form}
	return render(request,'blogs/new_blog.html',context)

都看到这里了,不妨点个赞八~

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:40:12  更:2022-08-06 10:43:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 12:26:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码