龙空技术网

15.python学习笔记-用户账户

吃饱了的饭团 62

前言:

现在朋友们对“html用户管理”大概比较注意,大家都需要了解一些“html用户管理”的相关资讯。那么小编也在网上网罗了一些关于“html用户管理””的相关文章,希望大家能喜欢,兄弟们快快来学习一下吧!

上一章我们基于Django实现了一个简单的“学习笔记”Web应用程序。这个Web应用程序存在一个问题:A用户可以访问B用户的学习笔记。

本章我们将新增accounts应用程序,建立一个身份注册和验证系统,支持用户登录、用户注册和用户管理自己创建的主题等功能。

项目改进

1.新增accounts应用程序

Django项目由多个应用程序组成,它们协同工作,让项目成为一个整体。我们新增应用程序“accounts”,执行如下命令:

python manage.py startapp accounts

会生成accounts目录:

2.注册accounts应用程序

在项目配置文件settings.py中添加自定义应用:

3.注册accounts应用程序URL匹配定义

修改项目urls.py,将accounts应用程序的URL匹配定义注册到项目中:

from django.contrib import adminfrom django.urls import path, includeurlpatterns = [    path('admin/', admin.site.urls),    path('', include('accounts.urls', namespace='accounts')),    path('', include('learning_logs.urls', namespace='learning_logs')),]

4.创建登录和注册页面

1)URL模式

在“accounts”中新建urls.py:

"""Defines URL patterns for accounts."""from django.urls import path, includefrom . import viewsapp_name = 'accounts'urlpatterns = [    # Include default auth urls.    path('', include('django.contrib.auth.urls')),    # Registration page.    path('register/', views.register, name='register'),]

2)视图

修改“accounts”中的views.py,从数据库获取和处理数据后,传递给模板根据数据渲染出界面:

from django.shortcuts import render, redirectfrom django.contrib.auth import loginfrom django.contrib.auth.forms import UserCreationFormdef register(request):    # 注册新用户    if request.method != 'POST':        # 生成一个空表单        form = UserCreationForm()    else:        # 处理用户创建表单.        form = UserCreationForm(data=request.POST)        # 检查表单数据        if form.is_valid():            new_user = form.save()            # 登录并且重定向到主页.            login(request, new_user)            return redirect('learning_logs:index')    # 将表单放入上下文传递到模版渲染.    context = {'form': form}    return render(request, 'registration/register.html', context)

3)模版

在“accounts”中新建目录“templates”及其子目录“registration”,并且在“registration”中创建login.html和register.html。

完整目录结构:

login.html:

{% extends 'learning_logs/base.html' %}{% block content %}  {% if form.errors %}    <p>用户名或者密码不对,请重新输入。</p>  {% endif %}  <form action="{% url 'accounts:login' %}" method='post'>    {% csrf_token %}    {{ form.as_p }}    <button name="submit">登录</button>  </form>{% endblock content %}

register.html:

{% extends "learning_logs/base.html" %}{% block content %}  <form action="{% url 'accounts:register' %}" method='post'>    {% csrf_token %}    {{ form.as_p }}    <button name="submit">注册</button>  </form>{% endblock content %}

修改“learning_logs/templates/learning_logs”下的base.html:

<p>  <a href="{% url 'learning_logs:index' %}">学习笔记</a> -  <a href="{% url 'learning_logs:topics' %}">主题</a> -  {% if user.is_authenticated %}    你好, {{ user.username }}.  {% else %}    <a href="{% url 'accounts:register' %}">注册</a> -    <a href="{% url 'accounts:login' %}">登录</a>  {% endif %}</p>{% block content %}{% endblock content %}{% if user.is_authenticated %}  <hr />  <form action="{% url 'accounts:logout' %}" method='post'>    {% csrf_token %}    <button name='submit'>注销</button>  </form>{% endif %}

修改项目settings.py,新增如下配置,设置登录或者注销重定向的页面:

LOGIN_REDIRECT_URL = 'learning_logs:index'LOGOUT_REDIRECT_URL = 'learning_logs:index'

5.限制访问

没有登录的情况下,访问主题等相关链接,应该重定向到登录页面。修改“learning_logs"的view.py"使用@login_required限制访问。

from django.shortcuts import render, redirectfrom django.contrib.auth.decorators import login_requiredfrom django.http import Http404from .models import Topic, Entryfrom .forms import TopicForm, EntryFormdef index(request):    """The home page for Learning Log."""    return render(request, 'learning_logs/index.html')@login_requireddef topics(request):    """Show all topics."""    topics = Topic.objects.filter(owner=request.user).order_by('date_added')    context = {'topics': topics}    return render(request, 'learning_logs/topics.html', context)@login_requireddef topic(request, topic_id):    """Show a single topic and all its entries."""    topic = Topic.objects.get(id=topic_id)    # Make sure the topic belongs to the current user.    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)@login_requireddef new_topic(request):    """Add a new topic."""    if request.method != 'POST':        # No data submitted; create a blank form.        form = TopicForm()    else:        # POST data submitted; process data.        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')    # Display a blank or invalid form.    context = {'form': form}    return render(request, 'learning_logs/new_topic.html', context)@login_requireddef new_entry(request, topic_id):    """Add a new entry for a particular topic."""    topic = Topic.objects.get(id=topic_id)    if request.method != 'POST':        # No data submitted; create a blank form.        form = EntryForm()    else:        # POST data submitted; process data.        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)    # Display a blank or invalid form.    context = {'topic': topic, 'form': form}    return render(request, 'learning_logs/new_entry.html', context)@login_requireddef edit_entry(request, entry_id):    """Edit an existing entry."""    entry = Entry.objects.get(id=entry_id)    topic = entry.topic    if topic.owner != request.user:        raise Http404    if request.method != 'POST':        # Initial request; pre-fill form with the current entry.        form = EntryForm(instance=entry)    else:        # POST data submitted; process data.        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)

修改项目settings.py,新增如下配置,设置跳转页面:

LOGIN_URL = 'accounts:login'

6.将数据关联到用户

我们需要将数据关联到用户,修改模型Topic,新增关联到用户的外键;历史已有Topic数据迁移;还要修改相关的视图和模版。

1)修改模型Topic

修改“learning_logs"的models.py:

from django.db import modelsfrom django.contrib.auth.models import Userclass Topic(models.Model):    """A topic the user is learning about."""    text = models.CharField(max_length=200)    date_added = models.DateTimeField(auto_now_add=True)    # 新增关联到用户的外键,User是默认提供的类    owner = models.ForeignKey(User, on_delete=models.CASCADE)    def __str__(self):        """Return a string representation of the model."""        return self.textclass Entry(models.Model):    """Something specific learned about a topic."""    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):        """Return a simple string representing the entry."""        return f"{self.text[:50]}..."

2)历史已有Topic数据迁移

我们之前已经创建了部分Topic,需要将这些数据迁移到指定用户,默认选择admin用户。使用Django Shell查看admin用户的用户ID:

python manage.py shell

我们得到了admin用户的用户ID:1,执行“生成数据迁移SQL相关的py文件”命令:

python manage.py makemigrations learning_logs

选择选项1,设置默认值1:

执行数据迁移:

python manage.py migrate

完成数据迁移后,查看迁移数据:

3)限制用户管理自己创建的主题

修改“learning_logs"的views.py:

修改topics函数,只能查询用户自己创建的主题;

修改topic函数,检查是否为当前登录用户;

修改edit_entry函数检查是否为当前登录用户;

修改new_topic函数,设置创建主题的关联用户。

from django.shortcuts import render, redirectfrom django.contrib.auth.decorators import login_requiredfrom django.http import Http404from .models import Topic, Entryfrom .forms import TopicForm, EntryFormdef index(request):    """The home page for Learning Log."""    return render(request, 'learning_logs/index.html')@login_requireddef 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_requireddef topic(request, topic_id):    """Show a single topic and all its entries."""    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)@login_requireddef new_topic(request):    """Add a new topic."""    if request.method != 'POST':        # No data submitted; create a blank form.        form = TopicForm()    else:        # POST data submitted; process data.        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')    # Display a blank or invalid form.    context = {'form': form}    return render(request, 'learning_logs/new_topic.html', context)@login_requireddef new_entry(request, topic_id):    """Add a new entry for a particular topic."""    topic = Topic.objects.get(id=topic_id)    if request.method != 'POST':        # No data submitted; create a blank form.        form = EntryForm()    else:        # POST data submitted; process data.        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)    # Display a blank or invalid form.    context = {'topic': topic, 'form': form}    return render(request, 'learning_logs/new_entry.html', context)@login_requireddef edit_entry(request, entry_id):    """Edit an existing entry."""    entry = Entry.objects.get(id=entry_id)    topic = entry.topic    #检查是否为当前登录用户    if topic.owner != request.user:        raise Http404    if request.method != 'POST':        # Initial request; pre-fill form with the current entry.        form = EntryForm(instance=entry)    else:        # POST data submitted; process data.        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)

7.切换到中文环境

Django默认使用英文和UTC时区,比如:鉴权页面中的用户名会显示"UserName"。可以通过修改项目的setting.py文件切换到中文环境。

LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'

项目测试

1.完整目录结构

2.启动服务器

python manage.py runserver

3.使用浏览器访问

4.显示默认主页

5.点击主题

当前未登录,会跳转到登录界面。

6.点击注册

按照填写要求输入用户名(test)和密码,如果不符合要求,会提示错误。

完成注册后,会跳转到主页,显示“你好,test”:

7.点击主题

显示当前主题列表:

创建新主题:

显示新创建的主题:

点击主题名称,创建新条目:

显示创建的新条目:

点击编辑条目,保存修改:

显示编辑过的条目:

点击学习笔记,回到主页:

点击注销,退出登录:

点击登录,输入用户名密码:

登录成功后,跳转到主界面:

标签: #html用户管理 #python当前用户 #python用户管理 #python用户管理系统