Django【学习笔记】在线项目

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)#内容

完成映射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 %}
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

网页:
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 %}

成果展示






访问其他用户内容

用户注册

后续有时间的话可能会更新:用户内容展示在一个大厅中,其他用户都可以看到的功能,然后用户注册可以用验证码发送QQ邮箱进行验证,学习完书本上的内容了,再加点常见的功能上去,美滋滋

|—(0.0)—|(起立站直,叉会腰~0.0~)

持续学习中,python,java,俺来啦!

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值