目录

前言

一、博客

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章答案相关推荐

  1. python从入门到实践13章答案

    系列文章目录  python从入门到实践12章答案 python从入门到实践14章答案 目录 前言 一.13-1星星 二.13-2更逼真的星星 三.13-3雨滴 四.13-4连绵细雨 五.13-5 侧 ...

  2. python从入门到实践18章答案

    目录 前言 一.新项目 二.简短的条目 三.Django API 四.比萨店 1.创建虚拟环境.安装Django.创建项目.创建数据库.创建应用程序 2.定义模型 3.激活模型 4.向管理网站注册模型 ...

  3. python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 用户输入和while循环 课后练习...

    题目: 7-8 熟食店 :创建一个名为sandwich_orders 的列表,在其中包含各种三明治的名字:再创建一个名为finished_sandwiches 的空列表.遍历列 表sandwich_o ...

  4. python从入门到实践课后题答案第7章_《Python从入门到实践》--第七章 while循环 课后练习...

    题目: 7-4 比萨配料 :编写一个循环,提示用户输入一系列的比萨配料,并在用户输入'quit' 时结束循环.每当用户输入一种配料后,都打印一条消息,说我们会在比萨 中添加这种配料. 7-5 电影票 ...

  5. python从入门到实践课后题答案第7章_【《Python编程: 从入门到实践》习题答案--第七章:】...

    #本章节代码中暂不涉及try-catch,所以默认为用户输入的符合所需要的输入类型 # 7-1 汽车租赁 : 编写一个程序, 询问用户要租赁什么样的汽车, 并打印一条消息, 如"Let me ...

  6. python 数据挖掘 简书_[Python数据挖掘入门与实践]-第一章开启数据挖掘之旅

    1.数据挖掘简介(略) 2.使用Python和IPython Notebook 2.1.安装Python 2.2.安装IPython 2.3.安装scikit-learn scikit-learn是用 ...

  7. python从入门到实践15章的几个自己的小程序

    练习15-1自己的答案 #加入python画图的库 pyplot import matplotlib.pyplot as plt #生成一个list input_values= list(range( ...

  8. python数据挖掘入门与实践-第一章-用最简单OneR算法对Iris植物分类

    前言: 这本书其实有配套代码的来着,但是有点坑的是,里面的代码对应的版本是有点旧的,用的时候会警告或者已经报错.甚至有些代码书里提了但是却没有写进去,要自己去摸索.我是每一章都跟着代码示例,把每一个步 ...

  9. python从入门到实践18章django存在问题_第18章 Django入门 P371

    声音简介-感谢粉丝NN娜娜小天使的打赏,此音频即日起以24小时/天,1次/小时的速度更新,直至完结~ 特别说明: 此音频仅作为更好地阅读此书的辅助工具,请大家购买正版书籍. 所有音频全部免费供大家试听 ...

最新文章

  1. [YTU]_2444( C++习题 对象转换)
  2. linux c语言链表的简单应用之创建链表
  3. telnet命令---Linux学习笔记
  4. Activity和Service的生命周期-----Activity学习笔记(一)
  5. Spring State Machine:它是什么,您需要它吗?
  6. Windows编程之网络之邮件槽通讯
  7. 对TRIM SCSI命令的一些分析
  8. 若不能细水长流地书写内心的温柔,那轰轰烈烈的一幕一幕不过是日后回忆自己爱无能的证据罢了。...
  9. python,numpy中np.random.choice()的用法详解及其参考代码
  10. eclipse快捷键 自动生成get set方法,转到所调用的方法
  11. 备案 前置或专项审批的内容
  12. symantec BESR 异机恢复
  13. Could not mount the media/drive ‘D:\......./VBoxGuestAdditions.iso‘ (VERR_PDM_MEDIA_LOCKED)
  14. layui 时间控件 只显示时分或者分秒
  15. Aug.2019_Memory
  16. oracle导入dmp文件数据不全,oracle导入dmp文件(恢复数据)
  17. 868-超详细 DNS 协议解析
  18. 你踩过几个?盘点微信H5小游戏开发中的那些坑
  19. 闭关修炼(十二) NIO
  20. bash: 无法执行二进制文件: 可执行文件格式错误

热门文章

  1. java角度_Java Math.toDegrees()弧度转换成角度
  2. OpenCV学习笔记(六)—— OpenCV for Android打开相机
  3. 人人都想买湖景房!湖景房优缺点你知道吗?
  4. 程序员钱多多准备应聘拼多多
  5. Paypal+本地支付,是跨境外贸收款最好的解决方案!
  6. 怎么修改服务器密码忘了怎么办啊,华为云怎么修改服务器密码忘记
  7. AndroidSDK的目录详解
  8. 产品之 2B、2C与2G
  9. 数据的处理方法及触摸屏终端
  10. 算法竞赛-ch2-水仙花数