07.01 django

一、manage.py    管理django的命令行工具

命令:python manage.py diffsettings  查看现在与默认值有什么不同。


python manage.py   查看命令

runserver   0.0.0.0:8080、shell、makemigrations、startspp  blog等。


二、1、init.py     空文件,是一个包

2、settings    配置文件

import os

Python的系统编程的操作模块,可以处理文件和目录

ROOT_URLCONF 

URLconf 告诉 Django 在这个站点中那些 Python的模块将被用到

3、urls.py    像是网站的目录

4、wsgi       web  server gateway interface web服务器网关接口,WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化

"""
Django settings for dailyfresh_14 project.

Generated by 'django-admin startproject' using Django 1.8.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

import sys
sys.path.insert(1, os.path.join(BASE_DIR, "apps"))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'f5ua%&s6#(47t_s_=2o-zobciv_3wz!x7v-4bvlte)fks3&we9'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# DEBUG = False

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tinymce',#富文本编辑器
    'haystack',#搜索框架
    'users',
    'goods',
    'orders',
    'cart'
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'dailyfresh.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'dailyfresh.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'localhost',
        'PORT': 3306,
        'USER':'root',
        'PASSWORD':'mysql',
        'NAME':'dailyfresh_14',
    },
    'slave':{
        'ENGINE':'django.db.backends.mysql',
        'HOST':'localhost',
        'PORT':'3306',
        'USER':'root',
        'PASSWORD':'mysql',
        'NAME':'dailyfresh_14',
    }
 }

#读写分离路由器
DATABASE_ROUTERS = ["utils.db_router.MasterSlaveDBRouter"]

# django认证系统使用的用户模型
AUTH_USER_MODEL = "users.User"

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]

# Email
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'Zhang1987'
EMAIL_FROM = '天天生鲜<[email protected]>'

# 缓存
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/4",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}


# Session
# http://django-redis-chs.readthedocs.io/zh_CN/latest/#session-backend

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

# 登录的url, login_required 装饰器使用
LOGIN_URL = "/users/login"

# 使用的文件存储工具
DEFAULT_FILE_STORAGE = "utils.fastdfs.storage.FastDFSStorage"

# FastDFS使用的配置信息
FASTDFS_CLIENT = os.path.join(BASE_DIR, "utils/fastdfs/client.conf")
FASTDFS_URL = "http://192.168.108.57:8888/"

# tinymce配置参数
TINYMCE_DEFAULT_CONFIG = {
    'theme': 'advanced',
    'width': 600,
    'height': 400,
}

# haystack配置信息
HAYSTACK_CONNECTIONS = {
    'default': {
        # 使用whoosh引擎
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        # 索引文件路径
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}

# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

# 支付宝配置参数
ALIPAY_APPID = "2016081600258081"
ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"

# 收集静态文件的目录
STATIC_ROOT = "/home/python/Desktop/static"









三、session    一次会话

一次会话,淘宝购物车信息存在数据库,不会放session,因为只是一次会话,退出就没了,京东购物车可以放session里。

京东唯品会可以放session,设置周期,慎用,最好不要存集合,存储信息量少,而且一直存在的。用request.

session可以用数据库、内存、文件存储,django就是数据库存储。

集群:view放在服务器上,model放在服务器上,合在一起,完成搭建。集群共享session所以要用到redis,或me'mcached等缓存服务器存储,共享session

request.session.pop('username')

flush()都清空

缓存和内存:

不同点:内存一般加工成内存条,后期安装到主板上,可插拔;缓存一般焊接在主板上,或者集成在CPU中。这是表面的差别。

四、rest方式和get方式

/ddd/sss        ddd/ddd?haha=


五、get和post的区别

get是向服务器获取数据,post是向服务器传送数据。

在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。

 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。


路径:

"""dailyfresh_14 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Add an import:  from blog import urls as blog_urls
    2. Add a URL to urlpatterns:  url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import include, url
from django.contrib import admin
import users.urls
import goods.urls
import tinymce.urls
import haystack.urls
import cart.urls
import orders.urls

urlpatterns = [
    #url(r'^admin/', include(admin.site.urls)),
    url(r'^admin/', admin.site.urls),
    url(r'^tinymce/', include(tinymce.urls)),
    url(r'^search/', include(haystack.urls)),
    url(r'^users/', include(users.urls, namespace="users")),
    url(r'^cart/', include(cart.urls, namespace="cart")),
    url(r'^orders/', include(orders.urls, namespace="orders")),
    url(r'^', include(goods.urls, namespace="goods")),
]
from django.conf.urls import url

from users import views
from django.contrib.auth.decorators import login_required

urlpatterns = [
    # url(r'^register$', views.register, name="register"),
    url(r'^register$', views.RegisterView.as_view(), name="register"),
    url(r'^active/(?P<token>.+)$', views.ActiveView.as_view(), name="active"),
    url(r'^login$', views.LoginView.as_view(), name="login"),
    url(r'^logout$', views.LogoutView.as_view(), name="logout"),
    # url(r'^address$', login_required(views.AddressView.as_view()), name="address"),
    url(r'^address$', views.AddressView.as_view(), name="address"),
    url(r'^info$', views.UserInfoView.as_view(), name="info"),
]




登陆:

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.views.generic import View
#from django.core.urlresolvers import reverse
from django.urls import reverse
import re
from users.models import User, Address
from django import db
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings
from itsdangerous import SignatureExpired
from celery_tasks.tasks import send_active_email
from django.contrib.auth import authenticate, login, logout
from utils.views import LoginRequiredMixin
from django_redis import get_redis_connection
from goods.models import GoodsSKU
import json

# Create your views here.

#
# def register(request):
#     """用户注册"""
#     # 用户的请求方式
#     if request.method == "GET":
#         # 处理get请求方式,提供页面
#         return render(request, "register.html")
#     else:
#         # 处理post请求方式,处理注册数据
#         return HttpResponse("这是post请求返回的页面")


class RegisterView(View):
    """用户注册"""
    def get(self, request):
        """处理get请求, 提供注册页面"""
        return render(request, "register.html")

    def post(self, request):
        """处理post请求,处理注册数据"""
        # 获取前端发送的数据/参数
        user_name = request.POST.get("user_name")
        password = request.POST.get("pwd")
        email = request.POST.get("email")
        allow = request.POST.get("allow")

        # 参数校验
        if not all([user_name, password, email]):
            # 如果参数不完整,从定向到注册页面
            return redirect(reverse("users:register"))

        if not re.match(r"^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$", email):
            # 如果email格式不正确
            return render(request, "register.html", {"errmsg": "邮箱格式不正确!"})

        if allow != "on":
            # 如果用户没有勾选协议
            return render(request, "register.html", {"errmsg": "请同意协议!"})

        # 进行业务逻辑处理
        # 将密码加密
        # 将用户数据保存到数据库中
        # user = User()
        # user.save()
        # 使用django的认证系统创建用户
        try:
            user = User.objects.create_user(user_name, email, password)
        except db.IntegrityError:
            # 如果抛出此异常,表示用户已经注册
            return render(request, "register.html", {"errmsg": "用户已注册!"})

        # 将用户的激活状态设置为假
        user.is_active = False
        user.save()

        # 生成激活token
        token = user.generate_active_token()

        # 使用celery发送邮件
        send_active_email.delay(email, user_name, token)

        # 返回给前端结果
        return redirect(reverse("goods:index"))


class ActiveView(View):
    """激活"""
    def get(self, request, token):
        # 根据token 解析,获取用户的id
        # 创建转换工具(序列化器)
        s = Serializer(settings.SECRET_KEY, 3600)
        # 解析
        try:
            ret = s.loads(token)
        except SignatureExpired:
            # 如果出现异常,表示token过期,返回信息给用户
            return HttpResponse("激活链接已过期")

        # 更新用户在数据库中的激活状态
        user_id = ret.get("confirm")
        # 查询数据库
        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            # 用户不存在
            return HttpResponse("用户不存在")

        user.is_active = True
        user.save()

        # 返回信息给用户
        return redirect(reverse("users:login"))


class LoginView(View):
    """登录"""
    def get(self, request):
        """提供登录页面"""
        return render(request, "login.html")

    def post(self, request):
        """处理登录请求"""
        user_name = request.POST.get("username")
        password = request.POST.get("pwd")
        remembered = request.POST.get("remembered")

        if not all([user_name, password]):
            return redirect(reverse("users:login"))

        #
        # password = sha256(password)
        # User.objects.get(username=user_name, password=password)

        # 使用django的认证系统
        user = authenticate(username=user_name, password=password)
        if user is None:
            # 表示用户的认证失败
            return render(request, "login.html", {"errmsg": "用户名或密码错误"})

        # 表示用户认证成功
        # 判断用户的激活状态
        if user.is_active is False:
            # 表示用户未激活
            return render(request, "login.html", {"errmsg": "用户名尚未激活"})

        # 在session中保存用户的登录状态信息
        login(request, user)

        # 处理记住用户名的逻辑
        if remembered != "on":
            # 不需要记住用户状态
            # 使用set_expiry设置 session 有效期
            request.session.set_expiry(0)
        else:
            # 需要记住用户状态
            request.session.set_expiry(None)

        # 将cookie中的购物车数据与redis中的购物车数据合并
        # 从cookie中获取购物车数据
        cart_json = request.COOKIES.get("cart")
        if cart_json is not None:
            cart_cookie = json.loads(cart_json)
        else:
            cart_cookie = {}

        # 从redis中获取购物车数据
        redis_conn = get_redis_connection("default")
        cart_redis = redis_conn.hgetall("cart_%s" % user.id)

        # 进行合并
        # cart_redis.update(cart_cookie)
        for sku_id, count in cart_cookie.items():
            # 在redis中的键与值都是bytes类型, 在cookie中的sku_id是str类型
            sku_id = sku_id.encode()  # 将str类型的sku_id转为bytes类型
            if sku_id in cart_redis:  # {b'1': b'3'}
                # cookie中有的商品,在redis中也有,进行数量求和,再设置到redis对应的购物车中
                origin_count = cart_redis[sku_id]
                count += int(origin_count)

            cart_redis[sku_id] = count

        # 将合并的购物车数据保存到redis中
        if cart_redis:
            redis_conn.hmset("cart_%s" % user.id, cart_redis)

        # 清除cookie中的购物车数据
        # 登录成功,根据next参数跳转页面
        next = request.GET.get("next")
        if next is None:
            # 如果没有next参数,跳转到主页
            response = redirect(reverse("goods:index"))
        else:
            # 如果next存在,跳转到next路径
            response = redirect(next)

        response.delete_cookie("cart")
        return response


class LogoutView(View):
    """退出"""
    def get(self, request):
        """"""
        # 将用户的session数据删除 ,使用logout将用户的session数据删除
        logout(request)
        return redirect(reverse("goods:index"))


class AddressView(LoginRequiredMixin, View):
    """用户地址"""
    def get(self, request):
        # 获取登录的用户
        user = request.user

        # 获取地址信息
        #
        # Address.objects.filter(user=user).order_by("create_time")[0]
        #
        # user.address_set.order_by("create_time")[0]
        #
        try:
            address = user.address_set.latest("create_time")
        except Address.DoesNotExist:
            # 如果地址信息不存在
            address = None

        context = {
            # "user": user,  # django的模板中可以直接使用user模板变量
            "address": address
        }

        return render(request, "user_center_site.html", context)

    def post(self, request):
        """修改地址信息"""
        user = request.user
        recv_name = request.POST.get("recv_name")
        addr = request.POST.get("addr")
        zip_code = request.POST.get("zip_code")
        recv_mobile = request.POST.get("recv_mobile")

        if all([recv_name, addr, zip_code, recv_mobile]):
            # address = Address(
            #     user=user,
            #     receiver_name=recv_name,
            #     detail_addr=addr,
            #     zip_code=zip_code,
            #     receiver_mobile=recv_mobile
            # )
            # address.save()
            Address.objects.create(
                user=user,
                receiver_name=recv_name,
                detail_addr=addr,
                zip_code=zip_code,
                receiver_mobile=recv_mobile
            )
        return redirect(reverse("users:address"))


class UserInfoView(LoginRequiredMixin, View):
    """用户中心"""
    def get(self, request):
        user = request.user

        # 获取地址信息
        # Address.objects.all().order_by("-create_time")[0]
        # Address.objects.filter().order_by("-create_time")

        try:
            address = user.address_set.latest("create_time")
        except Address.DoesNotExist:
            # 如果地址信息不存在
            address = None

        # 从django_redis中拿到一个与redis的连接对象
        redis_conn = get_redis_connection("default")

        # 从redis中查询用户的历史记录信息
        sku_ids = redis_conn.lrange("history_%s" % user.id, 0, 4)

        # sku_ids = [5,6,3,9,1]

        # 从数据库中查询商品的信息
        # select * from goods_sku where id in ()
        # skus = GoodsSKU.objects.filter(id__in=sku_ids)

        skus = []
        for sku_id in sku_ids:  # [5,6,3,9,1]
            sku = GoodsSKU.objects.get(id=sku_id)
            skus.append(sku)

        # 形成模板所用的变量,渲染模板
        context = {
            "address": address,
            "skus": skus   # [5,6,3,9,1]
        }
        return render(request, "user_center_info.html", context)

猜你喜欢

转载自blog.csdn.net/GAOSHIQI5322688/article/details/80872157