在线购物系统

创建产品目录模型(models)

image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)

由于我们会在模型(models)中和图片打交道,打开 shell ,用下面的命令安装 Pillow :

        pip isntall Pillow==2.9.0

因为使用ImageField来保存产品图片,需要开发服务器来服务上传图片文件。编辑myshop项目的settings.py文件,添加以下设置:

        MEDIA_URL ='/media/'

        MEDIA_ROOT = os.path.join(BASE_DIR,'media/')

MEDIA_URL是基础 URL:它为用户上传的媒体文件提供服务

MEDIA_ROOT是一个本地路径:媒体文件就在这个路径下,并且是由我们动态的将BASE_DIR添加到它的前面而得到的。

为了让 Django 给通过开发服务器上传的媒体文件提供服务,编辑myshop中的urls.py文件,添加如下代码:

if settings.DEBUG: 

        urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

记住,我们仅仅在开发中像这样提供静态文件服务。在生产环境下,你不应该用 Django 来服务静态文件。


class Meta:

        ordering = ('name',) 

        index_together = (('id','slug'),)

index_together元选项来指定id和slug字段的共同索引。我们定义这个索引,因为我们准备使用这两个字段来查询产品,两个字段被索引在一起来提高使用双字段查询的效率。


class CategoryAdmin(admin.ModelAdmin): 

        list_display = ['name', 'slug'] 

        prepopulated_fields = {'slug': ('name',)}

使用 prepopulated_fields 属性来指定那些要使用其他字段来自动赋值的字段。


购物车实现

        使用 Django 的会话框架(seesion framework)来保存购物车。在购物车最终被完成或用户下单之前,购物车将会保存在会话中。我们需要为购物车和购物车里的商品创建额外的 Django 模型(models)。

        会话中间件使当前会话在request对象中可用。你可以用request.seesion连接当前会话,它的使用方式和 Python 的字典相似。会话字典接收任何默认的可被序列化为 JSON 的 Python 对象。

        现在,你需要把购物车和会话关联起来。购物车像下面这样工作

        1.当需要一个购物车时,我们检查顾客是否已经设置了一个会话键( session key)。如果会话中没有购物车,我们就创建一个新的购物车,然后把它保存在购物车的会话键中。

        2.对于连续的请求,我们在会话键中执行相同的检查和获取购物车内物品的操作。我们在会话中检索购物车的物品和他们在数据库中相关联的Product对象。


上下文处理器----(模版标签?)

        上下文处理器是一个接收request对象为参数并返回一个已经添加了请求上下文字典的 Python 函数。他们在你需要让什么东西在所有模板都可用时迟早会派上用场。  

例:from .cart import Cart 

        def cart(request):

               return{'cart': Cart(request)}

        如你所见,一个上下文处理器是一个函数,这个函数接收一个request对象作为参数,然后返回一个对象字典,这些对象可用于所有使用RequestContext渲染的模板。在我们的上下文处理器中,我们使用request对象实例化了购物车,然后让它作为一个名为cart的参数对模板可用。

创建订单模型

        一个模型用来保存订单的详细信息,第二个模型用来保存购买的物品,包括物品的价格和数量。


Redis配置

        1.进入到redis目录下:cd~/java/redis-3.2.5

        2.运行make命令:make

        执行完后,redis已经成功下载到了本地,第一次运行make命令,命令可能会不存在,会自动弹出安装的一个窗口,点击确定安装即可

        3.输入src/redis-server启动redis服务:src/redis-server

        如果把服务停掉,再重新输入src/redis-server启动服务时,会报Redis Creating Server TCP listening socket *:6379: unable to bind socket的错误,是因为启动时没指定redis.conf文件,这个文件在解析后的redis-3.2.5文件夹下,进入到redis-3.2.5文件夹下,输入如下命令就可以启动服务了:src/redis-serverredis.conf

在src目录下,有个内置的客户端工作redis-cli,输入src/redis-cli命令打开客户端

cd java/redis-3.2.5/

src/redis-cli

ping

set foo bar

get foo

以上ping命令返回PONG,说明服务已经可以正常使用,并通过set命令,设置了foo变量的值是bar


使用Redis实现一个简单的推荐系统

    1. settings.py(和 Redis 服务器建立连接)

            REDIS_HOST = 'localhost'

            REDIS_PORT = 6379

            REDIS_DB = 1


redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令(比如,SET命令对应与StrictRedis.set方法)。Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。 简单说,官方推荐使用StrictRedis方法。

        r = redis.StrictRedis(host=settings.REDIS_HOST,

                                                port=settings.REDIS_PORT,

                                                db=settings.REDIS_DB)

1. 得到所给 `Product` 对象的产品 ID

2. 迭代所有的产品 ID。对于每个 "id" ,我们迭代所有的产品 ID 并且跳过所有相同的产品,这样我们就可以得到和每个产品一起购买的产品。

3. 我们使用 "get_product_id()" 方法来获取 Redis 产品键。对于一个 ID 为 33 的产品,这个方法返回键 `product:33:purchased_with` 。这个键用于包含和这个产品被一同购买的产品 ID 的有序集

4. 我们把有序集中的每个产品 "id" 的评分加一。评分表示另一个产品和所给产品一起购买的次数。


1. 得到所给 "Product" 对象的 ID

2. 如果只有一个产品,我们就检索一同购买的产品的 ID,并按照他们的购买时间来排序。这样做,我们就可以使用 Redis 的 "ZRANGE"命令。我们通过 "max_results"属性来限制结果的数量。

3. 如果有多于一个的产品被给予,我们就生成一个临时的和产品 ID 一同创建的 Redis 键。

4. 我们把包含在每个所给产品的有序集中东西的评分组合并相加,我们使用 Redis 的 "ZUNIONSTORE"命令来实现这个操作。"ZUNIONSTORE"命令执行了对有序集的所给键的求和,然后在新的 Redis 键中保存每个元素的求和。你可以在这里阅读更多关于这个命令的信息:http://redisio/commands/ZUNIONSTORE 。我们在临时键中保存分数的求和。

5. 因为我们已经求和了评分,我们或许会获取我们推荐的重复商品。我们就使用 "ZREM"命令来把他们从生成的有序集中删除。

6. 我们从临时键中检索产品 ID,使用 "ZREM"命令来按照他们的评分排序。我们把结果的数量限制在"max_results"属性指定的值内。然后我们删除了临时键。

7. 最后,我们用所给的 `id` 获取 `Product` 对象,并且按照同样的顺序来排序。


1.Redis Zincrby :Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment

2.Redis Zrange:Redis Zrange 返回有序集中,指定区间内的成员。其中成员的位置按分数值递增(从小到大)来排序。具有相同分数值的成员按字典序(lexicographical order )来排列。

如果你需要成员按值递减(从大到小)来排列,请使用ZREVRANGE命令。

下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。

你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。

3.Redis Zunionstore:命令计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination

默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 。

Redis Zrem:命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。

当 key 存在但不是有序集类型时,返回一个错误。

注意:在 Redis 2.4 版本以前, ZREM 每次只能删除一个元素。


Celery的使用

        Celery是Python开发的分布式任务调度模块,Celery本身不含消息服务,它使用第三方消息服务来传递任务,目前,Celery支持的消息服务有RabbitMQ、Redis甚至是数据库,当然Redis应该是最佳选择。


指定消息队列(发送和接受消息的传输者):

celery = Celery('tasks', broker='redis://localhost:6379/0')

celery = Celery('hello',broker='amqp://guest@localhost//')

Celery 用消息通信,通常使用中间人(Broker)在客户端和职程间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给进程


        Celery 是一个分发队列,它可以处理大量的信息。它既可以执行实时操作也支持任务调度。使用 Celery 不仅可以让你很轻松的创建异步任务还可以让这些任务尽快执行,但是你需要在一个指定的时间调度他们执行。

安装 Celery

让我们安装 Celery 然后把它整合进你的项目中。用下面的命令安装 Celery:

pip install celery==3.1.18

        Celery 需要一个消息代理(message broker)来管理请求。这个代理负责向 Celery 的 worker 发送消息,当接收到消息时 worker 就会执行任务。让我们安装一个消息代理。

        有几个 Celery 的消息代理可供选择,包括键值对储存,比如 Redis 或者是实时消息系统,比如 RabbitMQ。我们会用 RabbitMQ 配置 Celery ,因为它是 Celery 推荐的 message worker。


安装 RabbitMQ

        RabbitMQ 是默认的中间人,所以除了需要你要使用的中间人实例的 URL 位置, 它并不需要任何额外的依赖或起始配置:

        BROKER_URL='amqp://guest:guest@localhost:5672//'

        如果你用的是 Linux,你可以用下面这个命令安装 RabbitMQ :

                apt-get install rabbitmg

        如果你需要在 Mac OSX 或者 Windows 上安装 RabbitMQ,你可以在这个网站找到独立的支持版本:

        https://www.rabbitmq.com/download.html

在安装它之后,使用下面的命令执行 RabbitMQ

rabbitmg-server


步骤一:创建celery.py

from __future__ import absolute_import

import  os

from  celery  import  Celery

from  django.conf  import  settings

# set the default Django settings module for the 'celery' program.

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'picha.settings')

app = Celery('picha')

# Using a string here means the worker will not have to

# pickle the object when using Windows.

app.config_from_object('django.conf:settings')

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task(bind=True)

def debug_task(self):

print('Request: {0!r}'.format(self.request))

步骤二:引入celery应用

     为了确保在django启动时加载了celery应用,在settings.py旁边新建__init__.py,并添加以下代码到__init__.py中。

from__future__importabsolute_import

# This will make sure the app is always imported when

# Django starts so that shared_task will use this app.

from.celery  import  appascelery_app


打开另外一个 shell ,使用以下命令开启 celery worker :

celery -A myshop worker -l info

发送任务

sendmail.delay(...)

监控 Celery

你或许想要监控执行了的异步任务。下面就是一个基于 web 的监控 Celery 的工具。你可以用下面的命令安装 Flower:

pip install flower

celery -A myshop flower


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容