Django 项目分析后得到的某些结论

项目下的 urls 篇
urlpatterns = [ ] 其中主要是包含有各个 app 的路由
示例:

url(r'^users/', include('users.urls', namespace='users')),

url(r'^admin/', admin.site.urls),
settings 中的基础知识
INSTALLED_APPS = [ ] 存放创建好的app名称(app注册)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
    '创建好的app名称',
]
MIDDLEWARE = [] 中间件
TEMPLATES = [ ] 模板文件 

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['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',
            ],
        },
    },
]

'DIRS'可以修改为 

'DIRS': [os.path.join(BASE_DIR, 'templates')],
DATABASES  = { } 数据库 配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '数据库',
        'USER': '用户名',
        'PASSWORD': '密码',
        'CHARSET': '字符集',
        'HOST': 'IP地址',
        'PORT': '端口',
    }
}

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'webshop',
        'USER': 'root',
        'PASSWORD': 'root',
        'CHARSET': 'UTF-8',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
设置中文

LANGUAGE_CODE = 'zh-hans'
时间显示为北京时间

TIME_ZONE = 'Asia/Shanghai'
配置 static 静态目录

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

暂时还没有接触到的点(慎用)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

# hash加密使用的盐值
SALT_KEY = "Hello"

LOGIN_URL = '/users/login'

项目的 __init__ 文件中添加的内容

import pymysql

pymysql.install_as_MySQLdb()

app 的urls(创建的.py文件)

导入 views 

from . import views

urlpatterns = [
    url(r'^login/$', views.user_login, name='user_login'),
    url(r'^register/$', views.register, name='register'),
]
使用 (?P<views 中的函数参数名称>d+) 获取传递进来的参数给 views 中函数的参数

urlpatterns = [
    url(r'^(?P<s_id>d+)/detail_store', views.detail_store, name='detail_store'),
    url(r'^(?P<s_id>d+)/(?P<status>d+)/status_store', views.status_store, name='status_store'),
]
urlpatterns = [
    url(r'^(?P<number>d+)/(?P<goods_id>d+)/shop_into/$', views.shop_into, name='shop_into'),
    url(r'^list_car/$', views.list_car, name='list_car'),
    url(r'^(?P<shopcar_id>d+)/del_car/$', views.del_car, name='del_car'),
]
urlpatterns = [
    url(r'^order_confirm/$', views.order_confirm, name='order_confirm'),
    url(r'^order_pay/$', views.order_pay, name='order_pay'),
    url(r'^order_done/$', views.order_done, name='order_done'),
    url(r'^order_list/$', views.order_list, name='order_list'),
    url(r'^(?P<order_id>d+)/order_desc/$', views.order_desc, name='order_desc'),

]
url(r'^路由地址/$', views.函数名, name='名称'),

url(r'^(?P<函数参数名称>d+)/路径名/$', views.函数名, name='名称'),
关于路由系统,这里只是写出了最简单的写法,此处只是根据读程序获取到的部分知识

app 的 models,为 views 作基础,views在获取到urls中的请求后,会调用一些方法
创建主键 -> 1.11.14 自动创建 id 列 
在外键关联时,自动加上 _id 名称
 
id = models.AutoField(primary_key=True)
创建字符串 name 列 ,使用 models.CharField 

country = models.CharField(max_length=255, default='中国',verbose_name='城市')

area = models.CharField(max_length=50, verbose_name='收货人县/区/')
使用 bool 类型

数据字段名称 = models.BooleanField(default=False, verbose_name='xxx')

is_default = models.BooleanField(default=False, verbose_name='是否是默认地址')
int 类型 , 使用 models.IntegerField

age = models.IntegerField(default='20', verbose_name='用户年龄')

status = models.IntegerField(default=0, verbose_name='店铺状态')

goods_count = models.IntegerField(verbose_name='购买数量')
image 图片类型 使用 models.ImageField

变量名 = models.ImageField(upload_to='图片路径', default='图片名', verbose_name='名称')
变量名 = models.ImageField(upload_to='图片路径')


logo = models.ImageField(upload_to='static/images/logo', default='static/images/logo/goods-style1.png', verbose_name='商品类型图标')

path = models.ImageField(upload_to='static/images/goods', default='static/images/goods/default.jpg', verbose_name='商品图片')

goods_image = models.ImageField(upload_to='static/images/goods')

cover = models.ImageField(upload_to='static/images/store/', default='static/images/store/default.jpg', verbose_name='店铺封面')

header = models.ImageField(upload_to='static/images/headers', default='static/images/headers/default.jpg', verbose_name='用户头像')
text 描述 使用 models.TextField
变量名 = models.TextField(verbose_name= '名称')
变量名 = models.TextField(null=True, blank=True,verbose_name= '名称')

intro = models.TextField(verbose_name='商品类别描述')

intro = models.TextField(null=True, blank=True, verbose_name='商品图片描述')
float 浮点数类型,使用 models.FloatField
变量名 = models.FloatField(verbose_name='名称')
变量名 = models.FloatField(default=0.00, verbose_name='名称')

price = models.FloatField(verbose_name='商品价格')

allMoney = models.FloatField(default=0.00, verbose_name='总计')
datetime 使用 models.DateTimeField
变量名 = models.DateTimeField(auto_now_add=True, verbose_name='名称')

openTime = models.DateTimeField(auto_now_add=True, verbose_name='开店时间')

注:可以添加 datetime.now 用来在创建时,指定当前时间
foreignkey 外键 , 使用 models.ForeignKey

变量名 = models.ForeignKey(类名, null=True, blank=True, on_delete=models.CASCADE, verbose_name='名称')

parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父级地址')
from app名称.models import 类名

变量名 = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')
注:类名可以是外部导入或本models.py中创建的类名

from users.models import User

user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='地址所属')
一个models 类可以存在两个外键

goodsStore = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')
goodsType = models.ForeignKey(类名, on_delete=models.CASCADE, verbose_name='名称')


from store.models import Store
goodsStore = models.ForeignKey(Store, on_delete=models.CASCADE, verbose_name='商品所属店铺')
goodsType = models.ForeignKey(GoodsType, on_delete=models.CASCADE, verbose_name='商品类型')
从 django.contrib.auth.models 导入 User

from django.contrib.auth.models import User

user = models.ForeignKey(User, on_delete=models.CASCADE)
一对一 使用 models.OneToOneField
变量名 = models.OneToOneField(User, on_delete=models.CASCADE)

user = models.OneToOneField(User, on_delete=models.CASCADE)
在这里补充一点,字段还存在一对多和多对多

app 中的 views 
def 函数名(request):
    代码块
    return 语句(是否存在参数)

def 函数名(request,参数(一个或多个)):
    代码块
    return 语句(是否存在参数)

@装饰器(一个或多个)
def 函数名(request):
    代码块
    return 语句(是否存在参数)

@装饰器(一个或多个)
def 函数名(request,参数(一个或多个)):
    代码块
    return 语句(是否存在参数)
关于def 函数定义时,request 后面的参数
在进行路由分发时,使用 
url(r'^(?P<g_id>d+)/goods_detail/$', views.goods_detail, name='goods_detail'),

进行 get 请求传递进来的参数会给 g_id ,因此在 goods_detail 函数中要设置一个参数名为 g_id 

def goods_detail(request, g_id):
    代码
注:有多少个?P<参数名> 就设置多少个参数,用来接收
代码块中可以使用到很多知识,此处只是该项目使用到的基础

request.method 
判断进行的哪一种请求方式,GET还是POST

if request.method == 'GET':
    pass
elif request.method == 'POST':
    pass
else:
    pass
models.类名.objects.filter(表中字段(user)=request.user)
filter 主要是用来过滤,使用了filter 之后还可以继续使用 filter进行过滤

address_list = models.Address.objects.filter(user=request.user)

对于使用了 filter 方法 的对象,可以使用 len 进行判断,是否已经存在

sto = models.Store.objects.filter(name=name)
if len(sto) == 1:
return render(request, 'store/store_add.html', {"msg": "商铺名称已存在,请重新输入"})
获取 post 方式提交的数据
request.POST['名称']

recv_name = request.POST['recv_name']

html 中数据如下,让name的值于名称相对应即可
<input type="text" name="recv_name" id="recv_name" autocomplete="off">

name = request.POST['name'].strip()
在进行获取数据时,可以添加 strip 进行字符串操作
对于 filter 获取到的数据可以进行遍历
address_list = models.Address.objects.filter(user=request.user)
并且遍历的元素对象具有 save 方法 可以修改字段
Address 是类名,user , is_default 是 Address 表中的字段

from . import models

address_list = models.Address.objects.filter(user=request.user)
for addr in address_list:
    addr.is_default = False
    addr.save()

使用 __in 时,可以直接写明在某一个变量中 [0,1]
stores = models.Store.objects.filter(user=request.user, status__in=[0, 1])
添加表的一行数据
括号中 = 前面的都是表中的字段,后面是对应的值
使用 save 进行保存

变量 = models.类名(字段1 = 值1, 字段2 = 值2, user=request.user)
变量 .save()


address = models.Address(recv_name=recv_name, recv_tel=recv_tel, province=province, city=city, area=area,
                                     street=street, desc=desc, is_default=True, user=request.user)

address.save()

goods = models.Goods(name=name, price=price, stock=stock, desc=desc, goodSize=goodSize, goodsType=goodsType,goodsStore=store )
goods.save()



id 自增列不用添加
在使用 filter 获取数据后,使用 order_by 进行排序

from app名称.models import 类名
变量名 = 类名.objects.filter(user=request.user).order_by('名称')


shop_cars = ShopCar.objects.filter(user=request.user).order_by('-createTime')
在 filter 中使用 =
变量名 = 类名.objects.filter(字段名=值)

goods_type1 = GoodsType.objects.filter(pk=1001)
在 filter 中使用 __in
变量名 = 类名.objects.filter(字段名__in=值)
变量名 = 类名.objects.filter(字段名__in=值)[:2]

goods1_list = Goods.objects.filter(goodsType__in=goods_type1_2)[:4]
在 filter 中使用 __isnull
变量名 = 类名.objects.filter(字段名__isnull=True)


allGoodsType = GoodsType.objects.filter(parent__isnull=True)
文件 files , 具体请查阅更多资料

变量名 = request.FILES['名称']

path = request.FILES['path']

cover = request.FILES['cover']
cover 为 html 中的 name 值 <input name="cover" type="file" ... >
使用 .get 获取数据

变量 = 类名.objects.get(字段=变量或值)

store_id = request.POST['goodsStore']
store = Store.objects.get(pk=store_id)
是否带有 models 主要看导入包的方式
from . import models

type2 = request.POST['type2']
goodsType = models.GoodsType.objects.get(pk=type2)
利用获取到的对象的字段属性进行赋值

变量 = models.Goods.objects.get(字段名1=参数)
变量= goods.字段名2
store = models.类名.objects.get(字段名1=字段名2)


goods = models.Goods.objects.get(pk=g_id)
goodsStore_id = goods.goodsStore_id
store = models.Store.objects.get(pk=goodsStore_id)

注:
字段名根据实际需要进行修改
获取所有数据 使用 all 
变量名 = models.类名.objects.all()

all_goods = models.Goods.objects.all()
获取 GET 参数
变量名1 = request.GET['名称']

parent_id = request.GET['parent_id']

进行查找数据
变量名2 = models.类名.objects.filter(字段=变量名1)

type2 = models.GoodsType.objects.filter(parent=parent_id)
使用 getlist 获取多个数据

变量 = request.POST.getlist('名称')

shopcar_id_list = request.POST.getlist('buy_goods_id')

进行查找数据
变量2 = app名.models.类名.objects.filter(字段名__in=变量)
shopcar_list
= shopcar.models.ShopCar.objects.filter(pk__in=shopcar_id_list)
关于字段中 user=request.user 的理解
MyOrder 中的 user 是 User 的外键,所以在使用时,要注意传递的属性还是一整个对象

my_order = models.MyOrder(user=request.user, address=addr, total=total)

user = models.ForeignKey(User, on_delete=models.CASCADE)
使用 字段_set 可以获取到外键的表的字段,具体详情请查阅更多资料

此处仅给出部分示例

for sc_id in shopcar_list:
    shopcart = shopcar.models.ShopCar.objects.get(pk=sc_id)
    order_item = models.MyOrderItem(goods_image=shopcart.goods.goodsimage_set.first().path,
                                    goods_name=shopcart.goods.name,
                                    goods_price=shopcart.goods.price,
                                    goods_count=shopcart.number,
                                    goods_money=shopcart.allMoney,
                                    my_order=my_order)
    order_item.save()
    total += shopcart.allMoney
my_order.total = total
my_order.save()
get 获取写法,比之前的更深入一些

@login_required
@require_GET
def shop_into(request, number, goods_id):
    goods = Goods.objects.get(pk=goods_id)
    user = request.user
    try:
        shop_car = models.ShopCar.objects.get(user=user, goods=goods)
        shop_car.number += int(number)
        shop_car.allMoney = shop_car.number*goods.price
        shop_car.save()
    except:
        shop_car = models.ShopCar(goods=goods, number=number, user=user)
        shop_car.allMoney = int(shop_car.number)*goods.price
        shop_car.save()
    return redirect(reverse('shopcar:list_car'))

在使用 get 方法时,其中的 = 左侧依旧为字段名,=右侧的为get 获取到的对象,user 为 request.user

goods = Goods.objects.get(pk=goods_id)
user = request.user
shop_car = models.ShopCar.objects.get(user=user, goods=goods)

request.user 拥有 id 属性

使用 get 可以获取到字段进行参与表达式运算

shop_car.allMoney = shop_car.number*goods.price
删除数据 使用 delete()
shopcar = models.ShopCar(pk=shopcar_id, user=user)
shopcar.delete()
使用 int 进行转换

status = models.IntegerField(default=0, verbose_name='店铺状态')


store = models.Store.objects.get(id=s_id)
store.status = int(status)
获取 session 使用 request.session

变量名 = request.session["名称"]
示例:

if code.lower() != request.session["code"].lower():
    return render(request, "users/user_login.html", {"msg": "验证码错误!!"})
使用 authenticate

from django.contrib.auth import authenticate
user = authenticate(username=username, password=password1)

password1 = utils.encryption(password)

# 密码加密
def encryption(key):
    pwd = hmac.new(key.encode('utf-8'), settings.SALT_KEY.encode('utf-8'), 'MD5')
    return pwd.hexdigest()

此时的 user 拥有 is_active 属性,判断是否登录状态
if user is not None:
    if user.is_active:
        login(request, user)
        try:
            return redirect(next_url)
        except:
            return redirect("/")
    else:
        return render(request, "users/user_login.html", {"msg": "您的账号已被锁定,请联系管理员"})
else:
    return render(request, "users/user_login.html", {"msg": "用户名或者密码错误"})
导入 User
from django.contrib.auth.models import User

user = User.objects.create_user(username=username, password=password)

user.save()
代码块介绍之后,进行return返回
return render(request, 'templates 下的文件夹名称/文件名.html', {'名称': 值})


return render(request, 'address/address_add.html', {'address_list': address_list})

可以存在多个参数,goods 为在app目录下templates 中的 goods 文件夹
return render(request, 'goods/goods_show.html', {'goods': goods, 'store': store, 'nums':nums})
return redirect(reverse('名称1:值1', kwargs={'参数名': 值}))
html 中的数据
<a href="{% url '名称1:值1' 空格 参数名 %}">内容</a>

store_id = request.POST['goodsStore']

return redirect(reverse('store:detail_store', kwargs={'s_id': store_id}))

在这里 'store:detail_store' 为 反向解析

<a href="{% url 'store:detail_store' store.id %}">查看详情</a>
from django.core.serializers import serialize

type1 = models.GoodsType.objects.filter(parent=parent_id)
return HttpResponse(serialize('json', type1))
#转换成json类型的字符串
return redirect(reverse('shopcar:list_car'))


<a href="{% url 'shopcar:list_car'%}" style="border: none;color: #00b7ee; 100px;height: 40px" >返回购物车</a>
from io import BytesIO

def code(request):
    img, msg = utils.create_code()
    f = BytesIO()
    img.save(f, "PNG")
    # 将验证码的值存储到session
    request.session["code"] = msg
    return HttpResponse(f.getvalue(), "image/png")

utils.py 文件,自己创建,如果需要可以复制粘贴
import hmac
import string
import random
from PIL import Image, ImageDraw, ImageFont
from django.conf import settings



# 密码加密
def encryption(key):
    pwd = hmac.new(key.encode('utf-8'), settings.SALT_KEY.encode('utf-8'), 'MD5')
    return pwd.hexdigest()


# 验证码
def getRandomChar(count=4):
    # 生成随机字符串
    # string模块包含各种字符串,以下为小写字母加数字
    ran = string.ascii_lowercase + string.ascii_uppercase + string.digits
    char = ''
    for i in range(count):
        char += random.choice(ran)
    return char


# 返回一个随机的RGB颜色
def getRandomColor():
    return random.randint(50, 150), random.randint(50, 150), random.randint(50, 150)


def create_code():
    # 创建图片,模式,大小,背景色
    img = Image.new('RGB', (120, 30), (255, 255, 255))
    # 创建画布
    draw = ImageDraw.Draw(img)
    # 设置字体
    font = ImageFont.truetype('ARIALUNI.TTF', 25)

    code = getRandomChar()
    # 将生成的字符画在画布上
    for t in range(4):
        draw.text((25*t+7, 0), code[t], getRandomColor(), font)

    # 生成干扰点 增加识别的难度
    for _ in range(random.randint(99, 110)):
        # 位置,颜色
        draw.point((random.randint(0, 120), random.randint(0, 30)), fill=getRandomColor())
    # 生成干扰线 增加识别的难度
    for _ in range(random.randint(8, 15)):
        begin = random.randint(0, 120), random.randint(0, 50)
        end = random.randint(0, 120), random.randint(0, 50)
        draw.line([begin, end], fill=getRandomColor())

    # 使用模糊滤镜使图片模糊
    # img = img.filter(ImageFilter.BLUR)
    return img, code

HTML 文件
此处只例举一些基本语句,具体用法请查阅相关资料
{% block 名称 %}{% endblock %}
进行继承模板
{% extends '名称.html' %}
{% csrf_token %}

服务器返回页面的同时向前端返回一串随机字符

post提交时服务器会验证这串字符来确保用户是在服务端返回的表单页面中提交的数据
<tbody>
{% for addr in address_list %}
<tr>
    <td>{{addr.字段1}}</td>
    <td>{{addr.字段2}}</td>
    <td>{{addr.字段3}}</td>
    <td>
        {% if addr.is_default %}
        默认地址
        {% endif %}
    </td>
</tr>
{% empty %}
<tr>提示信息</tr>
{% endfor %}
</tbody>
{% if request.user.username %}
    html 语句
{% else %}
    html 语句
{% endif %}
{{request.user.userinfo.nickname}}
<form action="{%url 'orders:order_done' %}" method="post">
<input type="hidden" name="sc" value="{{sc.id}}">
<span>{{shopcar.number}}</span>
下单时间:{{order.order_time|date:'Y-m-d G:i:s'}}<br>
{% if store.status == 0 %}
<span style="font-size: 16px">店铺状态:正在营业</span>
{% elif store.status == 1 %}
<span style="font-size: 16px">店铺休息</span>
{% endif %}
{{goods.desc|truncatechars:22}}
截取前22个字符
{% for t in type1 %}
<option value="{{t.id}}" >{{t.name}}</option>
{% endfor %}

html 下还有很多的用法,此处仅列举出了这些

django 项目获取链接
链接:https://pan.baidu.com/s/1oWcHHbSR0JHmqr9qCzZGwA 提取码:Hany

2020-07-24

原文地址:https://www.cnblogs.com/hany-postq473111315/p/13371390.html