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 djangoUsing cached Django-4.0.6-py3-none-any.whl (8.0 MB)
Collecting tzdataUsing 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... OKApplying 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 modelsclass 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 modelreturn self.title +'=='+ self.text
激活模型 Blog\Blog\settings.py
# Application definitionINSTALLED_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 adminfrom .models import BlogPostadmin.site.register(BlogPost)
使用管理网站创建几个简短的帖子,效果如下:
4.让用户输入数据
这一步我借鉴了另一篇文章的答案,并略作修改,原文在此:
白桃提拉米苏的答案
表单 新建 Blog\blogs\forms.py
from django import formsfrom .models import BlogPostclass BlogPostForm(forms.ModelForm):class Meta:model = BlogPostfields = ['title','text'] # 获取模型里的两个字段widgets = {'text': forms.Textarea(attrs={'cols':80})}
视图 Blog\blogs\views.py
from django.shortcuts import render,redirectfrom .models import BlogPostfrom .forms import BlogPostFormdef 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.titleif 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, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('blogs.urls')),
]
Blog\Blogs\urls.py
from django.urls import pathfrom . import viewsapp_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目录: BlogMode 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 definitionINSTALLED_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, includeapp_name = 'users'
urlpatterns = [# contain the default authentication URLpath('', 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, includefrom . import viewsapp_name = 'users'
urlpatterns = [# contain the default authentication URLpath('', include('django.contrib.auth.urls')),# register pagepath('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 UserCreationFormdef register(request):"""register a new user"""if request.method != 'POST':# display an empty registration formform = UserCreationForm()else:# process completed formsform = UserCreationForm(data=request.POST)if form.is_valid():new_user = form.save()# let the user log in automatically and# redirect to the home pagelogin(request, new_user)return redirect('blogs:index')# display an empty form and indicate that the form is invalidcontext = {'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 Http404from .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.usernew_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 = topicnew_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.topiccheck_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 = topicnew_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_requiredfrom .models import BlogPostfrom .forms import BlogPostFormdef 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.titleif 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 Userclass 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 modelreturn 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 pageif blogpost.owner != request.user:raise Http404if 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.usernew_blog.save()return redirect('blogs:index')context = {'form':form}return render(request,'blogs/new_blog.html',context)
都看到这里了,不妨点个赞八~
python从入门到实践19章答案相关推荐
- python从入门到实践13章答案
系列文章目录 python从入门到实践12章答案 python从入门到实践14章答案 目录 前言 一.13-1星星 二.13-2更逼真的星星 三.13-3雨滴 四.13-4连绵细雨 五.13-5 侧 ...
- python从入门到实践18章答案
目录 前言 一.新项目 二.简短的条目 三.Django API 四.比萨店 1.创建虚拟环境.安装Django.创建项目.创建数据库.创建应用程序 2.定义模型 3.激活模型 4.向管理网站注册模型 ...
- python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 用户输入和while循环 课后练习...
题目: 7-8 熟食店 :创建一个名为sandwich_orders 的列表,在其中包含各种三明治的名字:再创建一个名为finished_sandwiches 的空列表.遍历列 表sandwich_o ...
- python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 while循环 课后练习...
题目: 7-4 比萨配料 :编写一个循环,提示用户输入一系列的比萨配料,并在用户输入'quit' 时结束循环.每当用户输入一种配料后,都打印一条消息,说我们会在比萨 中添加这种配料. 7-5 电影票 ...
- python从入门到实践课后题答案第7章_【《Python编程: 从入门到实践》习题答案--第七章:】...
#本章节代码中暂不涉及try-catch,所以默认为用户输入的符合所需要的输入类型 # 7-1 汽车租赁 : 编写一个程序, 询问用户要租赁什么样的汽车, 并打印一条消息, 如"Let me ...
- python 数据挖掘 简书_[Python数据挖掘入门与实践]-第一章开启数据挖掘之旅
1.数据挖掘简介(略) 2.使用Python和IPython Notebook 2.1.安装Python 2.2.安装IPython 2.3.安装scikit-learn scikit-learn是用 ...
- python从入门到实践15章的几个自己的小程序
练习15-1自己的答案 #加入python画图的库 pyplot import matplotlib.pyplot as plt #生成一个list input_values= list(range( ...
- python数据挖掘入门与实践-第一章-用最简单OneR算法对Iris植物分类
前言: 这本书其实有配套代码的来着,但是有点坑的是,里面的代码对应的版本是有点旧的,用的时候会警告或者已经报错.甚至有些代码书里提了但是却没有写进去,要自己去摸索.我是每一章都跟着代码示例,把每一个步 ...
- python从入门到实践18章django存在问题_第18章 Django入门 P371
声音简介-感谢粉丝NN娜娜小天使的打赏,此音频即日起以24小时/天,1次/小时的速度更新,直至完结~ 特别说明: 此音频仅作为更好地阅读此书的辅助工具,请大家购买正版书籍. 所有音频全部免费供大家试听 ...
最新文章
- [YTU]_2444( C++习题 对象转换)
- linux c语言链表的简单应用之创建链表
- telnet命令---Linux学习笔记
- Activity和Service的生命周期-----Activity学习笔记(一)
- Spring State Machine:它是什么,您需要它吗?
- Windows编程之网络之邮件槽通讯
- 对TRIM SCSI命令的一些分析
- 若不能细水长流地书写内心的温柔,那轰轰烈烈的一幕一幕不过是日后回忆自己爱无能的证据罢了。...
- python,numpy中np.random.choice()的用法详解及其参考代码
- eclipse快捷键 自动生成get set方法,转到所调用的方法
- 备案 前置或专项审批的内容
- symantec BESR 异机恢复
- Could not mount the media/drive ‘D:\......./VBoxGuestAdditions.iso‘ (VERR_PDM_MEDIA_LOCKED)
- layui 时间控件 只显示时分或者分秒
- Aug.2019_Memory
- oracle导入dmp文件数据不全,oracle导入dmp文件(恢复数据)
- 868-超详细 DNS 协议解析
- 你踩过几个?盘点微信H5小游戏开发中的那些坑
- 闭关修炼(十二) NIO
- bash: 无法执行二进制文件: 可执行文件格式错误