搭建自己的博客(二十八):自定义用户模型
2、变化的部分
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- 根据屏幕自动响应布局 --> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title> {# 用来放标题 #} {% block title %} {% endblock %} </title> {# 加载css代码 #} <link rel="stylesheet" href="{% static 'bootstrap4.1/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/base.css' %}"> {% block header_extends %} {# 用来做头部扩展,如加载某些静态文件 #} {% endblock %} </head> <body> {# 导航栏 #} <nav class="navbar navbar-expand-lg navbar-light bg-light sticky-top"> <a class="navbar-brand" href="{% url 'home' %}">Felix Blog</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item nav-home"><a href="{% url 'home' %}" class="nav-link">首页</a></li> <li class="nav-item nav-blog"><a href="{% url 'blog_list' %}" class="nav-link">博客</a></li> </ul> <ul class="navbar-nav"> {% if not user.is_authenticated %} <li class="nav-item"> <a class="nav-link" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'register' %}?from={{ request.get_full_path }}">注册</a> </li> {% else %} <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {{ user.username }} </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{% url 'user_info' %}">个人资料</a> {% if user.is_staff or user.is_superuser %} <a class="dropdown-item" href="{% url 'admin:index' %}">后台管理</a> {% endif %} <div class="dropdown-divider"></div> <a class="dropdown-item" href="{% url 'logout' %}?from={{ request.get_full_path }}">登出</a> </div> </li> {% endif %} </ul> </div> </nav> {# 用来放内容 #} {% block content %} {% endblock %} <!-- Modal 登录模态框 --> <div class="modal fade" id="login_model" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <form id="login_model_form" action="" method="post"> <div class="modal-header"> <h5 class="modal-title">登录</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> {% csrf_token %} {% for field in login_model_form %} <label for="{{ field.id_for_label }}">{{ field.label }}</label> {{ field }} {% endfor %} <span id="login_model_tip" class="text-danger"></span> </div> <div class="modal-footer"> <button type="submit" class="btn btn-primary">登录</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> </div> </form> </div> </div> </div> <script> $('#login_model_form').submit(function (event) { $('#login_model_tip').text(''); event.preventDefault(); // 阻止原事件提交 $.ajax({ url: '{% url 'login_for_model' %}', type: 'POST', data: $(this).serialize(), cache: false, success: function (data) { if (data['status'] === 'SUCCESS') { window.location.reload(); } else { $('#login_model_tip').text('用户名或密码不正确') } } }); }) </script> {# js代码放在后面可以增加性能 #} <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="{% static 'js/jquery-3.3.1.min.js' %}"></script> <script src="{% static 'bootstrap4.1/popper.min.js' %}"></script> <script src="{% static 'bootstrap4.1/bootstrap.min.js' %}"></script> {# 导入资源建议放在js代码前 #} {# 用来放js代码 #} {% block js %} {% endblock %} </body> </html>
{% extends 'base.html' %} {% block title %} 我的博客|登录 {% endblock %} {% block content %} <div class="container"> <div class="col-xl-6 offset-xl-3"> {% if not user.is_authenticated %} <div class="card"> <h5 class="card-header">登录</h5> <div class="card-body"> <form action="" method="post"> {% csrf_token %} {% for field in login_form %} <label for="{{ field.id_for_label }}">{{ field.label }}</label> {{ field }} <p class="text-danger">{{ field.errors.as_text }}</p> {% endfor %} <span class="text-danger float-left">{{ login_form.non_field_errors }}</span> <input type="submit" value="登录" class="btn btn-primary float-right"> </form> </div> </div> {# 未登录跳转到首页 #} {% else %} <script> window.location.href = '{% url 'home' %}' </script> {% endif %} </div> </div> {% endblock %} {% block js %} {# 将首页这个按钮设置激活状态 #} <script> $(".nav-home").addClass("active").siblings().removeClass("active"); </script> {% endblock %}
{% extends 'base.html' %} {% block title %} 我的博客|注册 {% endblock %} {% block content %} <div class="container"> {% if not user.is_authenticated %} <div class="col-xl-6 offset-xl-3"> <div class="card"> <h5 class="card-header">注册</h5> <div class="card-body"> <form action="{% url 'register' %}" method="post"> {% csrf_token %} {% for field in reg_form %} <label for="{{ field.id_for_label }}">{{ field.label }}</label> {{ field }} <p class="text-danger">{{ field.errors.as_text }}</p> {% endfor %} <span class="text-danger float-left">{{ login_form.non_field_errors }}</span> <input type="submit" value="注册" class="btn btn-primary float-right"> </form> </div> </div> {% else %} <script> window.location.href = '{% url 'home' %}' </script> {% endif %} </div> </div> {% endblock %} {% block js %} {# 将首页这个按钮设置激活状态 #} <script> $(".nav-home").addClass("active").siblings().removeClass("active"); </script> {% endblock %}
{% extends 'base.html' %} {% block title %} 个人资料 {% endblock %} {% block content %} <div class="container"> <div class="col-xl-8 offset-xl-2"> <h2>{{ user.username }}</h2> {% if user.is_authenticated %} <ul> <li>昵称: <a href="">修改昵称</a></li> <li> 邮箱: {% if user.email %} {{ user.email }} {% else %} 未绑定 <a href="">绑定邮箱</a> {% endif %} </li> <li>上一次登录时间:{{ user.last_login|date:"Y-m-d H:i:s" }}</li> <li><a href="">修改密码</a></li> </ul> {% else %} {# 未登录跳转到首页 #} <script> window.location.href = '{% url 'home' %}' </script> {% endif %} </div> </div> </div> {% endblock %} {% block js %} {# 将首页这个按钮设置激活状态 #} <script> $(".nav-home").addClass("active").siblings().removeClass("active"); </script> {% endblock %}
from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User from .models import Profile # Define an inline admin descriptor for Employee model # which acts a bit like a singleton class ProfileInline(admin.StackedInline): model = Profile can_delete = False # Define a new User admin class UserAdmin(BaseUserAdmin): inlines = (ProfileInline,) list_display = ('username', 'nickname', 'email', 'is_staff', 'is_active', 'is_superuser') def nickname(self, obj): return obj.profile.nikename nickname.short_description = '昵称' # 后台字段 # Re-register UserAdmin admin.site.unregister(User) admin.site.register(User, UserAdmin) @admin.register(Profile) class ProfileAdmin(admin.ModelAdmin): list_display = ('user', 'nikename')
from django.db import models from django.contrib.auth.models import User class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) nikename = models.CharField(max_length=20, verbose_name='昵称',default='') def __str__(self): return '<Profile: {} for {}>'.format(self.nikename, self.user.username)