dailyfresh总结Django

django项目总结

1、setting文件配置

1.1 基本配置

INSTALLED_APPS = [
    'df_goods',  ## 创建应用时,应在此处注册应用,否则不能进行迁移
    'user',
    'haystack',
    'df_order',
]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates'# 在项目中创建templates文件夹,用来存放模板html
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        .......
]
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'freshdata',
        'HOST': 'localhost',
        'USER': 'root',
        'PASSWORD': '123456',
        'POST': 3306
    }
}
LANGUAGE_CODE = 'zh-hans'   # 中文

TIME_ZONE = 'Asia/Shanghai'  # 上海时间

# 在项目目录下创建static静态文件夹,存放照片,js,css文件
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

1.3 用户上传图片

# 网页上传照片
MEDIA_ROOT = os.path.join(BASE_DIR,'static')

模型models.py里
上传的照片将会保存在/static/film_img/目录下
class ImageInfo(models.Model):
    img = models.ImageField(upload_to='film_img', null=True, blank=True)
    imglink = models.ForeignKey('BlogInfo')

    def __str__(self):
        return self.imglink.title
1. 需要添加enctype="multipart/form-data"
2. 文件上传<input type="file" name="pic"><br>

<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
        <label for="">title</label><br>
        <input type="text" name="film_name"><br>
        <label for="">content</label><br>
        <textarea name="content" id="content1" cols="30" rows="10"></textarea><br>
        <input type="file" name="pic"><br>
        <input type="submit" value="添加"><br>
    </form>

1.4 全文检索插件

全文检索步骤
# 全文检索框架配置
HAYSTACK_CONNECTIONS = {
    'default': {
    搜索引擎whoosh_cn_backend已经替换掉原来的whoosh_backend
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        # 索引文件路径
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}

# 当执行增删改操作时自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

# 搜索结果会自动分页,每页多少个
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10

  1. pip install django-haystack==2.8 whoosh jieba
  2. 将haystack添加到应用里
  3. 在需要检索的应用中新建search_indexes.py,并复制代码 名字不能错
from haystack import indexes
from df_goods.models import GoodsInfo


class GoodsInfoIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        return GoodsInfo

    def index_queryset(self, using=None):
        return self.get_model().objects.all()
  1. 在templates目录下新建search/indexes/应用名的文件夹 search/indexes/df_goods
    在这里插入图片描述
  2. 设置whoosh
    在虚拟环境下的site_packages/haystack/backends目录下找到whoosh_backends.py
    复制一份命名为whoosh_cn_backends.py
    找到 analyzer=StemmingAnalyzer() 这句代码 替换成analyzer=ChineseAnalyzer()
    from jieba.analyse import ChineseAnalyzer 从结巴分词导入中文分词功能
    在这里插入图片描述
    python manage.py rebuild_index 生成 索引文件
    若有问题,则向上查看步骤是否出错
  3. 配置路由
    url(r’^search/’, include(‘haystack.urls’)),
    其实可以写成
    url(r’^$’, SearchView(), name=‘haystack_search’),
  4. 搜索按钮,将搜索代码变成表单,输入框的name属性的值是q
<div class="search_con fl">
    <form action="/search/" method="get">
        <input type="text" class="input_text fl" name="q" placeholder="搜索商品">
        <input type="submit" class="input_btn fr" name="" value="搜索">
    </form>
</div>
  1. 搜索的视图函数默认模板是templates/search/search.html
要将需要搜索的list.html复制一份并命名为search.html
只对page页码对象起作用,要添加object,比如原本的{{ pa.id}} 变成 {{ pa.object.id }}
<ul class="goods_type_list clearfix">
    {% for pa in page.object_list %}
        <li>
            <a href="/detail_{{ pa.object.id }}/"><img src="/static/{{ pa.object.gpic }}"></a>
            <h4><a href="/detail_{{ pa.object.id }}/">{% highlight pa.object.gtitle with query %}</a></h4>
            <div class="operate">
                <span class="prize">¥{{ pa.object.gprice }}</span>
                <span class="unit">{{ pa.object.gprice }}/{{ pa.object.gunit }}</span>
                <a href="#" class="add_goods" title="加入购物车" name="{{ pa.object.id }}"></a>
            </div>
        </li>
    {% empty %}
        <div class="no-post">没有搜索到你想要的结果!</div>
    {% endfor %}

</ul>
  1. 可以在应用中写搜索的视图函数,新建search_views.py,按照写代码
此时路由配置是url(r'^$', SearchView(), name='haystack_search')
from haystack.views import SearchView
from df_goods.models import *

class MySearchView(SearchView):
    def extra_context(self):
        context = super().extra_context()
        覆盖原来的搜索的视图函数,在原来的基础上向search.html页面
        传参数new
        gnew = GoodsInfo.objects.all().order_by('-id')[:2]
        context['new'] = gnew
        return context

1.5 调用支付宝接口

支付宝

非官方支付宝支付流程

  1. 在setting配置文件中添加支付宝id账号以及调用的url
setting配置中
# 支付宝
ALIPAY_APPID = "2016102500758593"

ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"
  1. 安装
    pip install python-alipay-sdk==1.1
    从 1.3.0升级上来的用户, 请先卸载pycrypto: pip uninstall pycrypto
    安装python-alipay-sdk
    pip install python-alipay-sdk --upgrade

  2. 随意在一个文件夹中打开cmd,生成密钥文件
    openssl
    OpenSSL> genrsa -out app_private_key.pem 2048 私钥
    OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
    OpenSSL> exit

  3. 将公钥的内容复制到
    支付宝沙盒链接
    获取支付宝的公钥

  4. 将app_public_key.pem复制一份并命名为alipay_public_key.pem,将获得的支付宝公钥复制在此文件中

  5. 将私钥和支付宝公钥文件复制到static文件中

  6. 在视图函数中配置

from django.conf import settings
import os
from alipay import AliPay
from django.core.paginator import Paginator
alipay = AliPay(
    appid=settings.ALIPAY_APPID,
    app_notify_url=None,   # 验证地址
    app_private_key_path=os.path.join(settings.STATICFILES_DIRS[0],'app_private_key.pem'),
    alipay_public_key_path=os.path.join(settings.STATICFILES_DIRS[0],'alipay_public_key.pem'),
    sign_type='RSA2',  # 加密方式
    debug=True,
)
@transaction.atomic
def pay_order(request):
......
.......
            
        elif pay_style == 'zfb':
            order_id = order1.oid
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=order_id,
                total_amount=str(total),
                subject=f'靓仔坚专属红包{order_id[:5]}.....',
                return_url='http://127.0.0.1:8000/check_pay/?order_id='+order_id,
                notify_url='http://127.0.0.1:8000/check_pay/?order_id='+order_id
            )
            # 将拼接的地址传到html中
            alipay_url = settings.ALIPAY_URL + '?' + order_string
            return JsonResponse({'res':'zfb','alipay_url':alipay_url})
    else:
        # 有问题就回滚到保存点
        transaction.savepoint_rollback(sid)
        return JsonResponse({'res': 0})
def check_pay(request):
    """登陆支付页面后,检验支付情况"""
    order_id = request.GET.get('order_id')
    order1 = OrderInfo.objects.get(oid=order_id)

    while True:
        time.sleep(1)
        # 调用alipay工具查询支付结果        
        response = alipay.api_alipay_trade_query(order_id)  # response是一个字典
        # 判断支付结果        
        print(response)
        code = response.get("code")  # 支付宝接口调用成功或者错误的标志        
        trade_status = response.get("trade_status")  # 用户支付的情况
        if code == "10000" and trade_status == "TRADE_SUCCESS":
            # 表示用户支付成功           
            # 返回前端json,通知支付成功
            order1.oIsPay = True
            order1.save()
            return redirect('/user_center/')
        elif code == "40004" or (code == "10000" and trade_status == "WAIT_BUYER_PAY"):
            # 表示支付宝接口调用暂时失败,(支付宝的支付订单还未生成) 后者 等待用户支付            
            # 继续查询            
            continue
        else:
            return JsonResponse({'res':0})

1.6 富文本编辑器

  1. 安装百度编辑器
    需要进入虚拟环境安装
    解压到项目中,打开Ueditor,在当前目录下打开终端,python setup.py install
  2. 在setting中 注册应用
    INSTALLED_APPS = [‘DjangoUeditor’,]
  3. 在项目urls中 配置路由
    url(r’^ueditor/’,include(‘DjangoUeditor.urls’))
  4. 使用UEditorField 替换原来的模型类中的字段
    UEditorField(width=1000,height=300,toolbars=‘full’)
    比如
content = UEditorField(width=1000,height=300,toolbars='full')

1.7 markdown

安装 markdown:
pip install markdown

def detail(request, num):
    # film = BlogInfo.objects.get(id=num)
    # 如果没有找到对象就返回404,找到了就正常返回
    film = get_object_or_404(BlogInfo, id=num)
    film.content = markdown.markdown(film.content, extensions={
        'markdown.extensions.extra',
        'markdown.extensions.codehilite',
        'markdown.extensions.toc'
    })
    form = CommentForm()  # 创建表单对象
    return render(request, 'blog/detail.html', {'film': film, 'form': form})
高亮 markdown.extensions.codehilite
  1. pip install pygments (高亮)
    原理:将代码块的每个单词加个span标签

  2. 将高亮样式文件放入静态文件

  3. 在h5页面中 引入高亮样式

 <link rel="stylesheet" href="/static/css/highlights/github.css">

2、模型

2.1 模型字段

DecimalField模型类的参数有两个

1、max_digits 整数部分的长度

2、decimal_places
小数部分的长度(保留的小数位数)

比如:666666.66

ototal = models.DecimalField(max_digits=6,decimal_places=2)  # 订单总价格

2.2 引用其他应用的模型

例如goods字段,引用了商品应用的GoodsInfo模型类

格式:应用名.模型类

class OrderDetailInfo(models.Model):
    goods = models.ForeignKey('df_goods.GoodsInfo')
    order = models.ForeignKey('OrderInfo')
    price = models.DecimalField(max_digits=5,decimal_places=2)
    count = models.IntegerField()

2.3 数据库问题

迁移步骤:

  1. python manage.py makemigrations
  2. python manage.py migrate

操作过程中,需要改字段,但修改不了,只能删表重建,并迁移。

问题1:

删表后无法重新建表

解决方法:

删除应用中migrations的initial.py文件以及其他的迁移文件

在这里插入图片描述
再重新迁移操作
如果依旧无法迁移,则在数据库中执行
delete from django_migrations where app = “your-app-name”;

清空有外键关联的表中内容
  • 清空表中内容
    truncate table your_table_name;
    有外键时:
    暂时关闭外键即可清空,再打开外键
    1、SET FOREIGN_KEY_CHECKS=0; 关闭外键
    2、SET FOREIGN_KEY_CHECKS=1; 开启外键

3、视图函数

3.1 ajax 和 form表单提交

  • ajax提交的方式一般是get
  • ajax的通式:(jquery)
视图函数返回的Jsonresponse({'is_ok':1})
$(function(){
	$.ajax({
        type: 'get',
        url: '/cart_ver/',
        data: {'good_id': '{{ good.id }}', 'count': anum},
        DataType: 'json'
    }).done(function (data) {
	    if (data.is_ok){
		 .......
		}
    })
})


$(function(){
	$.get(url,data,function(data){
	......
	})
})

form表单提交的方式有两种,GET和POST
如果POST提交的情况下,表单下应加上csrf验证 {% csrf_token %}

<form action="/login_ver/" method="post">
    {% csrf_token %}
    <input type="text" name="username" class="name_input" placeholder="请输入用户名" value={{ user_name }}>
    <div class="user_error">用户名输入错误或者不存在</div>
    <input type="password" name="pwd" class="pass_input" placeholder="请输入密码">
    <div class="pwd_error">密码输入错误</div>
    <div class="more_input clearfix">
        <input type="checkbox" name="remember" id="rem">
        <label>记住用户名</label>
        <a href="#">忘记密码</a>
    </div>
    <input type="submit" name="" value="登录" id="btn1" class="input_submit">
</form>

ajax和form的差距:
ajax提交不会刷新页面,form表单提交会刷新页面

-视图函数中获取ajax或form提交的请求,再由视图函数处理请求
只能接受一个请求

3.2 session和cookies

cookies是存放在客户端
session是存放在服务器
session一般保存客户id和密码

# 设置session
request.session['user_id'] = userinfo[0].id
request.session['username'] = username
request.session['pwd'] = pwds

# 获取session
user_id = request.session['user_id']
username = request.session['username']
pwd = request.session['pwd']

# 删除session
request.session.clear()

cookies设置
例如最近浏览商品

def detail(request,num):
    good = GoodsInfo.objects.get(id=num)
    # 点击后点击量加一
    good.gclick += 1
    good.save()
    # 除了推荐外的食物
    other = GoodsInfo.objects.exclude(id=num)
    types = TypeInfo.objects.filter(isDelete__isnull=False)
    # 最近浏览对象,设置cookies
    res = render(request,'detail.html',{'good':good,'other':other,'types':types})
    # 先获取cookies的recent,如果没有返回一个列表字符串
    recent_goods = request.COOKIES.get('recent','[]')
    ren = eval(recent_goods)  # 获得列表
    # ren = []
    # 如果该商品id不在列表中,那ren最前面添加此商品
    if num not in ren:
        ren.insert(0,num)
    if len(ren) > 5:
        # 如果超过五个,就把最后一个删除
        ren.pop()
    res.set_cookie('recent',str(ren))
    return res

def user_center(request):
    # 如果能获取到session,才能进入个人中心
    if request.session.get('username'):
        username = request.session.get('username')
        user = UserInfo.objects.get(user_name=username)  # user为具体对象
        # 一开始没有地址,则显示空
        addr = user.useradressinfo_set.all().filter(isselect=True)  # addr是对象集
        # 获取最近浏览的商品
        recents = request.COOKIES.get('recent','[]')
        ren = eval(recents)
        if ren:
            # 如果没有浏览商品则返回空列表
            ren_goods = [GoodsInfo.objects.get(id=num) for num in ren]
        else:
            ren_goods = []
        if addr:
            # 如果有数据
            data = addr[0]
        else:
            # 如果没数据,则addr为空
            data = addr

        return render(request, 'user_center_info.html', {'ren_goods':ren_goods,'title':'用户中心','user': user, 'username': username, 'addr': data, 'search': 1})
    else:
        return redirect('/login/')

3.3 数据库的事务

from django.db import transaction  # 导入事务模块
在需要事务的函数上添加装饰器
@transaction.atomic
def pay_order(request):
    # {'cid':cid,'pay_style':pay_style}
    pay_style = request.GET.get('pay_style')  # 支付方式
    cid = request.GET.getlist('cid')  # 要购买商品的id

    user_id = request.session['user_id']  # 用户id
    user = UserInfo.objects.get(id=user_id)  # 用户对象
    # 如果没有地址,不可以提交
    addr = user.useradressinfo_set.all().get(isselect=True)  # 默认地址
    sid = transaction.savepoint()  # 创建一个保存点,提交订单失败可回退到这一步
    if 没问题了就可以提交事务:
    	transaction.savepoint_commit(sid)
    else: 如果有问题就回滚到保存点
    	transaction.savepoint_rollback(sid)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值