2023.2.13,记录下我使用django开发名为”学习笔记“的项目,完成网站成功实现了用户注册,用户登录以及注销功能,实现用户自己仅能访问自己创建的日记功能等等。
在文章中主要记录代码以及在项目中遇到的问题:自己用的django版本和书籍上django版本(1.11)/头铁/
准备阶段
Package Version
------------------ -------
asgiref 3.6.0
backports.zoneinfo 0.2.1
Django 4.1.5
pip 20.2.1
reverse 0.1.0
setuptools 49.2.1
sqlparse 0.4.3
tzdata 2022.7
书籍:python从入门到实践
工具:PyCharm Community Edition 2022.3.2
浏览器:Microsoft Edge
python 3.8.6
项目的搭建
建立虚拟环境:在项目新建一个目录:learning_log,并在cmd用以下命令创建虚拟环境
B:\>学习笔记项目\learning_log>python -m venv 11_env
创建完毕激活虚拟环境,书上的是在bin目录
B:\学习笔记项目\11_env\Scripts>activate
激活成功:
(11_env) B:\学习笔记项目>
然后安装django
(11_env) B:\学习笔记项目>pip install Django
pip务必更新到最新的版本,不然后面可能会出现好多问题(我就是那个大冤种)
创建项目以及创建数据库:
(11_env) B:\>学习笔记项目\learning_log>django-admin.py startpoject learning_log
(11_env) B:\学习笔记项目>python manage.py migrate
创建应用程序
(11_env) B:\学习笔记项目>python manage.py startapp leaning_logs
在leaning_logs里创建模型:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
"""用户学习主题"""
text=models.CharField(max_length=200)
date_added=models.DateTimeField(auto_now_add=True)
owner=models.ForeignKey(User,on_delete=models.CASCADE)#设置用户创建的模型归自己所有
def __str__(self):
"""返回模型的字符串表示"""
return self.text
class Entry(models.Model):
'''学习到有关每个主题的具体知识'''
topic=models.ForeignKey(Topic,on_delete=models.CASCADE)
text=models.TextField()
date_added=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""返回模型的字符串表示"""
if len(self.text) > 50:
return_str = f"{self.text[:50]}..." # 只显示text的前50字符,省略号指出显示的并非整个条目,只输出f里面的[]
else:
return_str = f"{self.text[:50]}" # 只显示text的前50字符
return return_str
在setting里面加入应用程序,路径:B:\>学习笔记项目\learning_log>learning_log
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'learning_logs',#内容,主题
'users',#用户后面创建usersapp再写进去
]
注意:修改数据库,存储模型
(11_env) B:\学习笔记项目>leaning_log>python manage.py makemigrations learning_logs
...
(11_env) B:\学习笔记项目>leaning_log>python manage.py magrate
...
在models.py添加admin.py文件,向管理网站注册模型:
from django.contrib import admin
#引入模型到管理界面
from learning_logs.models import Topic,Entry
admin.site.register(Topic)#主题
admin.site.register(Entry)#内容
![](https://i-blog.csdnimg.cn/blog_migrate/f1e5f38c9027b182ada8779566cdeaef.png)
完成映射URL及其视图
learning_log的url.py:
from django.contrib import admin
from django.urls import path,include
from learning_logs.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')),#用户后面创建usersapp再写进去
path('',include('learning_logs.urls')),
]
django1.11版本是:
from django.urls import path,url
urlpatterns = [
url(r'^admin/',include(admin,site.urls)),
]
在learning_logs的views.py
from django.shortcuts import render,HttpResponse
from .models import Topic,Entry
from django.http import HttpResponseRedirect,Http404
from django.urls import reverse
from .forms import TopicForm,EntryForm
from django.contrib.auth.decorators import login_required#每个主题归特定客户所有
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)
#确认请求的主题是属于当前用户
if topic.owner!= request.user:
raise Http404
entries =topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request,'learning_logs/topic.html',context)
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(request.POST)
if form.is_valid():
#处理数据
#form.instance.owner = request.user#即用Form的instance 参数,来获取owner 属性,并用requset.user得到的当前用户赋值给此instance的owner。
new_topic=form.save(commit=False)
new_topic.owner= request.user
new_topic.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.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
if topic.owner!=request.user:#保护页面edit_entry,禁止用户输入路由访问其他用户的
raise Http404
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)
在每一个定义函数前加入:@login_required#每个主题归特定客户所有
form.instance.owner = request.user#即用Form的instance 参数,来获取owner 属性,并用requset.user得到的当前用户赋值给此instance的owner。
在learning_logs的urls.py文件
"定义learning_logs的URL模式"
from django.conf.urls import include
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [
path('', views.index, name='index'),
path('topics/', views.topics, name='topics'),
#特定主题详细内容
path('topics/<int:topic_id>/', views.topic, name='topic'),
#添加新主题的网页
path('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'),
]
django的1.11版本是不需要输入这个的:app_name = 'learning_logs'
forms.py
在B:\>学习笔记项目\learning_logs> 的目录下创建form.py 文件
from django import forms
from .models import Topic,Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
label={'text': ''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels={'text': ''}#定义空标签
widgets = {'text': forms.Textarea(attrs={'cols': 80})}#widget属性 表单元素,设置宽度为八十
网页
base.html(继承模板)
<P>
<a href="{% url 'learning_logs:index' %}">Learning Log</a> -
<a href="{% url 'learning_logs:topics' %}">Topics</a>-
{% if user.is_authenticated %}
你好,{{ user.username }}
<a href="{% url 'users:logout' %}">注销</a>
{% else %}
<a href="{% url 'users:register' %}">注册</a>-
<a href="{% url 'users:login' %}">登录</a>
{% endif %}
</P>
{% block content %}{% endblock content %}
![](https://i-blog.csdnimg.cn/blog_migrate/31cbb5f9add00ddb3bb3d2aeeb57a282.png)
index.html(主页)
{% extends "learning_logs/base.html" %}
{% block content %}
<p>这是一个可以保存学习笔记的网站<p>
{% endblock content %}
new_topic.html(主题部分)
{% extends "learning_logs/base.html" %}
{% block content %}
<p>添加一个新的主题:</p>
<form action="{% url 'learning_logs:new_topic' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">添加主题</button>
</form>
{% endblock content %}
new_entry.html(内容部分)
{% extends "learning_logs/base.html" %}
{% block content %}
<p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></p>
<p>添加新的内容</p>
<form action="{% url 'learning_logs:new_entry' topic.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">添加内容</button>
</form>
{% endblock content %}
edit_entry.html(内容部分)
{% extends "learning_logs/base.html" %}
{% block content %}
<p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></p>
<p>更改内容</p>
<form action="{% url 'learning_logs:edit_entry' entry.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">确认内容</button>
</form>
{% endblock content %}
topic.html(显示内容页面)
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topic: {{topic}}</p>
<P>Entries:</P>
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">添加新的内容</a>
</p>
<ul>
{% for entry in entries %}
<li>
<p>{{entry.date_added}}</p>
<p>{{entry.text|linebreaks}}</p>
<p>
<a href="{% url 'learning_logs:edit_entry' entry.id %}">修改内容</a>
</p>
</li>
{% empty %}
<li>我们没有主题</li>
{% endfor %}
</ul>
{% endblock content %}
topics.html(显示个人页面)
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a>
</li>
{% empty %}
<li>我们没有主题</li>
{% endfor %}
</ul>
<a href="{% url 'learning_logs:new_topic' %}">添加新主题</a>
{% endblock content %}
登录及注册
在B:\>学习笔记项目\ 创建新的app users
users\urls.py文件如下:
from django.conf.urls import include
from django.urls import path
from django.contrib.auth.views import LoginView
from . import views
app_name = 'users'
urlpatterns = [
path('login/',LoginView.as_view(template_name='users/login.html'), name='login'),#因Django 版本的改变,在url中的path方法需要修改,参考 Django的官方文献资料
path('logout/',views.logout_view, name='logout'),
#注册页面
path('register/',views.register, name='register'),
]
from django.contrib.auth.views import LoginView
from django.urls import path
书本上是:from django.contrib.auth.views import login
users\views.py文件如下:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse#登录
from django.contrib.auth import logout,login,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)
from django.contrib.auth import logout,login,authenticate#注册
from django.contrib.auth.forms import UserCreationForm
![](https://i-blog.csdnimg.cn/blog_migrate/739c34633c5b50d5731c40fce95eb589.png)
网页:
login.html
{% extends "learning_logs/base.html" %}
{% block content %}
{% if form.errors %}
<p>请输入您的用户名和密码,完成登录</p>
{% endif %}
<form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit" >登录</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
register.html
{% extends "learning_logs/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}" >
{% csrf_token %}
{{ form.as_p }}
<button name="submit" >注册</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
成果展示
![](https://i-blog.csdnimg.cn/blog_migrate/cf8c8966c410af3191a44dfe48c60e7d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8d67ed446d4f7103735cf937880c5b09.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8e0808ba06c83659436575c5f43ce460.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3d2b8e147c4eff881de875f336179d28.png)
![](https://i-blog.csdnimg.cn/blog_migrate/402bfc8f272718ac0f0f2af2e26f7af5.png)
访问其他用户内容
![](https://i-blog.csdnimg.cn/blog_migrate/de93f8c575cc77f25038247530679a6b.png)
用户注册
![](https://i-blog.csdnimg.cn/blog_migrate/bbf245c57740e581b565dd34c3d55472.png)
后续有时间的话可能会更新:用户内容展示在一个大厅中,其他用户都可以看到的功能,然后用户注册可以用验证码发送QQ邮箱进行验证,学习完书本上的内容了,再加点常见的功能上去,美滋滋
|—(0.0)—|(起立站直,叉会腰~0.0~)
持续学习中,python,java,俺来啦!