django项目1

本项目采用前后端分离的方式实现

一.立项

1.首先GIT上创建一个自己的项目

2.进入桌面,将项目克隆下来:git clone git的网址

3.用pycharm打开文件,将静态文件复制到根目录下,并进行提交

git add front_end_pc

git status

git commit -m '上传前端文件'

git push

4.使用前端node.js 提供的服务器live-server作为前端开发服务器使用。

安装node.js的版本控制工具nvm,在终端中执行

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

重新进入终端,使用nvm安装最新版本的node.js

nvm install node

安装live-server

npm install -g live-server

 进入前端的文件,输入:live-server就可以进行前端界面的访问(8080端口)

5.创建django项目并安装django restful framework (DRF)

     在.virtualenvs中创建项目虚拟环境:mkvirtualenv meiduo_fenghua -p python3

     pip install django==1.11.11

     pip install djangorestframework

     django-admin startproject  项目名称

     查找解释器位置:which python

     添加解释器给项目

     环境中添加runserver后运行manage.py

二.环境配置

1.修改settings.py文件

项目运行有开发环境和生产环境,flask项目通过工厂函数进行分配,django项目通过创建两个settings文件进行环境的区分

将原先的settings.py配置文件进行拆分:一个用于开发环境,一个用于生产环境

在同级目录创建settings包,里边定义两个py文件:dev(开发),prod(生产)

然后更改项目manage.py文件中的meiduo_mall.settings为meiduo_mall.settings.dev

部署的时候在wsgi.py 文件中将meiduo_mall.settings改为meiduo_mall.settings.prod即可

2.创建数据库并指定访问用户

create database meiduo_mall default charset=utf8;

为本项目创建数据库用户(不再使用root账户)

create user meiduo identified by 'meiduo'; 
grant all on meiduo_mall.* to 'meiduo'@'%'; 
flush privileges;

说明:

第一句:创建用户账号 meiduo, 密码 meiduo (由identified by 指明)

第二句:授权meiduo_mall数据库下的所有表(meiduo_mall.*)的所有权限(all)给用户meiduo在以任何ip访问数据库的时候('meiduo'@'%')

第三句:刷新生效用户权限

3.配置文件的基本配置

①添加DRF:在INSTALLED_APPS中添加'rest_framework'

②修改mysql数据库:

'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 数据库主机
        'PORT': 3306,  # 数据库端口
        'USER': 'meiduo',  # 数据库用户名
        'PASSWORD': 'meiduo',  # 数据库用户密码
        'NAME': 'meiduo_mall'  # 数据库名字
    }

 安装pymysql:pip install PyMySQL

在项目同名目录的init文件中将python3的指定成python2的MySQLdb

③ 配置redis数据库(redis和mysql都是CS架构,使用时需要启动服务)

安装redis数据库:pip install django-redis

添加配置信息:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    "session": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"

④语言和时区

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

⑤配置日志

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,  # 是否禁用已经存在的日志器
    'formatters': {  # 日志信息显示的格式
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    'filters': {  # 对日志进行过滤
        'require_debug_true': {  # django在debug模式下才输出日志
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {  # 日志处理方法
        'console': {  # 向终端中输出日志
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {  # 向文件中输出日志
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"),  # 日志文件的位置
            'maxBytes': 300 * 1024 * 1024,
            'backupCount': 10,
            'formatter': 'verbose'
        },
    },
    'loggers': {  # 日志器
        'django': {  # 定义了一个名为django的日志器
            'handlers': ['console', 'file'],  # 可以同时向终端与文件中输出日志
            'propagate': True,  # 是否继续传递日志信息
            'level': 'INFO',  # 日志器接收的最低日志级别
        },
    }
}

 注意:在meiduo_mall中添加logs文件夹,因为是空文件夹,所以创建.gitkeep文件,并在忽略文件中添加logs/*.log,自己的日志不能上传

⑥配置异常()

修改Django REST framework的默认异常处理方法,补充处理数据库异常和Redis异常。

新建utils/exceptions.py

from rest_framework.views import exception_handler as drf_exception_handler
import logging
from django.db import DatabaseError
from redis.exceptions import RedisError
from rest_framework.response import Response
from rest_framework import status

# 获取在配置文件中定义的logger,用来记录日志
logger = logging.getLogger('django')

def exception_handler(exc, context):
    """
    自定义异常处理
    :param exc: 异常
    :param context: 抛出异常的上下文
    :return: Response响应对象
    """
    # 调用drf框架原生的异常处理方法
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context['view']
        if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
            # 数据库异常
            logger.error('[%s] %s' % (view, exc))
            response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

 添加配置信息

REST_FRAMEWORK = {
    # 异常处理
    'EXCEPTION_HANDLER': 'meiduo_mall.utils.exceptions.exception_handler',
}

 三.导包路径说明

查看导包路径的方法:

在dev中

import sys

在BASE_DIR下边

print(sys.path)

['/home/python/Desktop/Meiduo/meiduo_mall','/home/python/Desktop/Meiduo',

'/home/python/.virtualenvs/meiduo_fenghua/lib/python35.zip', '/home/python/.virtualenvs/meiduo_fenghua/lib/python3.5', '/home/python/.virtualenvs/meiduo_fenghua/lib/python3.5/plat-x86_64-linux-gnu', '/home/python/.virtualenvs/meiduo_fenghua/lib/python3.5/lib-dynload', '/usr/lib/python3.5',

'/usr/lib/python3.5/plat-x86_64-linux-gnu', '/home/python/.virtualenvs/meiduo_fenghua/lib/python3.5/site-packages']

REST_FRAMEWORK = {
    # 异常处理
    'EXCEPTION_HANDLER': 'meiduo_mall.utils.exceptions.exception_handler',
}

从列表得知导包路径有/home/python/Desktop/Meiduo/meiduo_mall,

所以异常处理的导包路径为meiduo_mall.utils.exceptions.exception_handler

还有from XX import XX也一样,上边的列表已经指定了系统配置好的前半段路径,我们只需补充后半段即可。

四.用户模块(注册,登陆)

在meuduo/meiduo_mall/meiduo_mall下创建apps包用来存放所有应用,因为这个目录下就是处理业务逻辑的,而应用就是处理业务的。(等价于flask的moduels)

然后创建应用python ../../ manage.py startapp users

在应用的models文件中创建用户的模型类

django为我们提供了一个原生的用户模型类AbstractUser

INSTALLED_APPS 中的 'django.contrib.auth',就代表使用django默认用户认证系统,我们尽量打开他,用于站点的权限和组。且依赖于session的,所以数据库有一个表django_session,本项目不使用session做状态保持,而是修改默认的认证机制而使用JWT认证!!!!!!!!!!!!!!!我们只使用该机制(该机制很庞大)中的用户模型类AbstractUser

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() if six.PY3 else ASCIIUsernameValidator()

    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=30, 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 # 执行migrate时不执行迁移,所以要自定义模型类

    def clean(self):
        super(AbstractUser, self).clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Returns 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):
        "Returns the short name for the user."
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email], **kwargs)

 models中定义模型类

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    """用户模型类"""
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

因为替换了默认的AbstactUser,所以要重新配置

AUTH_USER_MODEL = 'users.User'

 然后注册app

'users.apps.UsersConfig'

为了适应AUTH_USER_MODEL,必须以users开头,所以还要追加导包路径
追加导包路径:/home/python/Desktop/Meiduo/meiduo_mall/meiduo_mall/apps

在BASE_DIR下边写

sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

然后进行数据库迁移即可:

python manage.py makemigrations

python manage.py migrate

结论:

AUTH_USER_MODEL = 'users.User'实现数据库中的表的数据维护的是User,否则维护的是原始的AbstractUser

猜你喜欢

转载自blog.csdn.net/weixin_31449201/article/details/81099263