美文网首页程序员Django
Django的用户表创建(四)

Django的用户表创建(四)

作者: 测试游记 | 来源:发表于2019-02-27 21:57 被阅读4次

    在完成了之前的事情之后,接下来就是实现注册功能了。
    首先进行基础的分析工作

    • 判断用户名是否为空,是否已注册
    • 判断邮箱是否为空,是否已注册
    • 判断密码是否为空,格式是否正确
      一般的注册操作还会有确认密码的输入,所以我们会在前端中增加一列。
    • 判断确认密码与密码是否相同

    请求方法POST

    url定义/register/

    请求参数:url路径参数

    参数 类型 前端是否必须传 描述
    username 字符串 用户输入的用户名
    password 字符串 用户输入的密码
    password_repeat 字符串 用户输入的重复密码
    email 字符串 用户输入的邮箱地址

    注:由于是post请求,在向后端发起请求时,需要附带csrf token

    加入我们需要完成注册,那就需要把这三个字段username,password,email存入到数据库中
    我们首先编写数据库相关的代码
    因为Django框架功能齐全自带数据库操作功能,所以我们可以很方便的完成数据库的设计。不过还是从最普通的开始了解吧。
    正常的情况我们如果操作数据库需要:

    • 创建数据库,设计表结构和字段
    • 使用 MySQLdb 来连接数据库,并编写数据访问层代码
    • 业务逻辑层去调用数据访问层执行数据库操作
      Django采用ORM的形式完成数据库的操作

    ORM是什么?:(在django中,根据代码中的类自动生成数据库的表也叫--code first)
    ORM:Object Relational Mapping(关系对象映射)
    类名对应------》数据库中的表名
    类属性对应---------》数据库里的字段
    类实例对应---------》数据库表里的一行数据
    obj.id obj.name.....类实例对象的属性

    也就是说django与数据库的交互被写在了黑盒子里面了,如果我们要用只需要知道输入,不用管黑盒子是MySQL、Oracle、sqlite还是其他乱七八糟的数据库,它都会按照我们的需求输出正确的操作。

    ORM系统
    下面我们打开apps/login/models.py开始编写数据库相关约束。
    id = models.AutoField() 
    username = models.CharField()
    password = models.CharField()
    email = models.EmailField()
    

    了解一下常用的类型,接触过数据库的应该都知道

    1. IntegerField : 整型,映射到数据库中的int类型。
    2. CharField: 字符类型,映射到数据库中的varchar类型,通过max_length指定最大长度。
    3. TextField: 文本类型,映射到数据库中的text类型。
    4. BooleanField: 布尔类型,映射到数据库中的tinyint类型,在使用的时候,传递True/False进去。如果要可以为空,则用NullBooleanField。
    5. DateField: 日期类型,没有时间。映射到数据库中是date类型,
      在使用的时候,可以设置DateField.auto_now每次保存对象时,自动设置该字段为当前时间。设置DateField.auto_now_add当对象第一次被创建时自动设置当前时间。
    6. DateTimeField: 日期时间类型。映射到数据库中的是datetime类型,
      在使用的时候,传递datetime.datetime()进去。
      但是写了这些还不够的,因为用户名,密码,邮箱等都需要进行一定的约束,id一半是作为主键
      知道了这个之后,就需要想办法解决了,但是受限于我的编码经验,所以我选择借鉴django大佬的代码。直接查看Django为admin编写的用户类
      from django.contrib.auth.models import AbstractUser按住ctrl+AbstractUser跳进去。
      以下是django中的源码:
    class AbstractUser(AbstractBaseUser, PermissionsMixin):
        """
        An abstract base class implementing a fully featured User model with
        admin-compliant permissions.
    
        Username and password are required. Other fields are optional.
        """
        username_validator = UnicodeUsernameValidator()
    
        username = models.CharField(
            _('username'),
            max_length=150,
            unique=True,
            help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
            validators=[username_validator],
            error_messages={
                'unique': _("A user with that username already exists."),
            },
        )
        first_name = models.CharField(_('first name'), max_length=30, blank=True)
        last_name = models.CharField(_('last name'), max_length=150, blank=True)
        email = models.EmailField(_('email address'), blank=True)
        is_staff = models.BooleanField(
            _('staff status'),
            default=False,
            help_text=_('Designates whether the user can log into this admin site.'),
        )
        is_active = models.BooleanField(
            _('active'),
            default=True,
            help_text=_(
                'Designates whether this user should be treated as active. '
                'Unselect this instead of deleting accounts.'
            ),
        )
        date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    
        objects = UserManager()
    
        EMAIL_FIELD = 'email'
        USERNAME_FIELD = 'username'
        REQUIRED_FIELDS = ['email']
    
        class Meta:
            verbose_name = _('user')
            verbose_name_plural = _('users')
            abstract = True
    
        def clean(self):
            super().clean()
            self.email = self.__class__.objects.normalize_email(self.email)
    
        def get_full_name(self):
            """
            Return the first_name plus the last_name, with a space in between.
            """
            full_name = '%s %s' % (self.first_name, self.last_name)
            return full_name.strip()
    
        def get_short_name(self):
            """Return the short name for the user."""
            return self.first_name
    
        def email_user(self, subject, message, from_email=None, **kwargs):
            """Send an email to this user."""
            send_mail(subject, message, from_email, [self.email], **kwargs)
    

    在变成我们自己的代码之前先了解以下里面的东西吧:

    • primary_key: 指定是否为主键。
    • unique: 指定是否唯一。
    • null: 指定是否为空,默认为False。
    • blank: 等于True时form表单验证时可以为空,默认为False。
    • default: 设置默认值。
    • DateField.auto_now: 每次修改都会将当前时间更新进去,只有调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及TimModel.save()方法才会调用e类才有的。
    • DateField.auto_now_add: 第一次添加进去,都会将当前时间设置进去。以后修改,不会修改这个值
      我们复制其中的username和email再稍加整改
      突然先到我们好像缺少了创建时间更新时间。而且这两个内容在全部表中都可以被应用到。所以我们封装一个基类好了。
    from django.db import models
    
    class ModelBase(models.Model):
        create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
        update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
    
        class Meta:
            # 为抽象模型类,用于其他模型来继承,数据库迁移时不会创建ModelBase表
            abstract = True
    

    所以我们的用户表的model文件就是:

    from django.db import models
    from utils.models import ModelBase
    
    
    class User(ModelBase):
        id = models.AutoField(primary_key=True)
        username = models.CharField(
            max_length=30,
            unique=True,
        )
        password = models.CharField(
            max_length=30,
        )
        email = models.EmailField()
    
        class Meta:
            db_table = "tb_user"  # 指明数据库表名
    
        def __str__(self):  # 这个__str__方法的作用将在查询时看到
            return f'User<id={self.id},username={self.username},email={self.email}'
    
    

    表名为tb_user

    数据库迁移

    运行manage.py
    找到Tools中的Run manage.py Task...
    首先输入makemigrations login
    再输入migrate login
    数据库迁移
    可以打开数据库可视化工具查看
    数据库展示
    以上就完成了用户表的创建,不过里面的一些约束条件什么的感觉还是有点问题,但是应该不影响正常的使用(无法应对破坏性的测试)。之后修改models之后在使用makemigrations [app name]migrate [app name]就可以修改表结构了。以后出问题了再改好了,问题驱动开发是比较合理的模式,毕竟在一开始就面面俱到难度不是一般的大。

    相关文章

      网友评论

        本文标题:Django的用户表创建(四)

        本文链接:https://www.haomeiwen.com/subject/kyequqtx.html