【发布时间】:2018-04-10 16:42:59
【问题描述】:
我已经编写了这个推荐引擎(基于示例 Antonio Mele 的 Django)。
使用 shell 测试时一切正常,在渲染的模板中可以看到推荐的产品。 但是,当通过应用程序完成订单时,不会创建或显示推荐。
我完全坚持这个,任何建议都非常感谢......
import redis
from django.conf import settings
from .models import Product
# connect to redis
r = redis.StrictRedis(host=settings.REDIS_HOST,port=settings.REDIS_PORT,db=settings.REDIS_DB)
class Recommender(object):
def get_product_key(self, id):
return 'product:{}:purchased_with'.format(id)
def products_bought(self, products):
product_ids = [p.id for p in products]
for product_id in product_ids:
for with_id in product_ids:
# get the other products bought with each product
if product_id != with_id:
# increment score for product purchased together
r.zincrby(self.get_product_key(product_id),with_id,amount=1)
def suggest_products_for(self, products, max_results=6):
product_ids = [p.id for p in products]
if len(products) == 1:
# only 1 product
suggestions = r.zrange(self.get_product_key(product_ids[0]),0, -1, desc=True)[:max_results]
else:
# generate a temporary key
flat_ids = ''.join([str(id) for id in product_ids])
tmp_key = 'tmp_{}'.format(flat_ids)
# multiple products, combine scores of all products
# store the resulting sorted set in a temporary key
keys = [self.get_product_key(id) for id in product_ids]
r.zunionstore(tmp_key, keys)
# remove ids for the products the recommendation is for
r.zrem(tmp_key, *product_ids)
# get the product ids by their score, descendant sort
suggestions = r.zrange(tmp_key, 0, -1,desc=True)[:max_results]
# remove the temporary key
r.delete(tmp_key)
suggested_products_ids = [int(id) for id in suggestions]
# get suggested products and sort by order of appearance
suggested_products = list(Product.objects.filter(id__in=suggested_products_ids))
suggested_products.sort(key=lambda x: suggested_products_ids.index(x.id))
return suggested_products
这是产品详细信息视图
def product_detail(request, id, slug):
language = request.LANGUAGE_CODE
product = get_object_or_404(Product, id=id, translations__language_code=language,
translations__slug=slug, available=True)
cart_product_form = CartAddProductForm()
r = Recommender()
recommended_products = r.suggest_products_for([product])
return render(request, 'shop/product/detail.html',
{'product': product, 'cart_product_form': cart_product_form,
'recommended_products': recommended_products })
购物车视图
def cart_detail(request):
cart = Cart(request)
for item in cart:
item['update_quantity_form'] = CartAddProductForm(initial={'quantity': item['quantity'], 'update':True})
coupon_apply_form = CouponApplyForm()
r = Recommender()
cart_products = [item['product'] for item in cart]
recommended_products = r.suggest_products_for(cart_products)
return render(request, 'cart/detail.html', {'cart': cart,'recommended_products': recommended_products,'coupon_apply_form': coupon_apply_form })
订单视图
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
r = Recommender()
cart_products = [item['product'] for item in cart]
recommended_products = r.suggest_products_for(cart_products,4)
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
order.save()
if cart.coupon:
coupon = cart.coupon
coupon.save()
order.discount = coupon.discount
order.save()
for item in cart:
OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
#emptying the cart
r = Recommender()
cart_products = [item['product'] for item in cart]
recommended_products = r.suggest_products_for(cart_products)
cart.clear()
#launch celery async task
order_created.delay(order.id)
request.session['order_id'] = order.id #set order.id session
return redirect(reverse('payment:process'))
else:
form = OrderCreateForm()
r = Recommender()
cart_products = [item['product'] for item in cart]
recommended_products = r.suggest_products_for(cart_products)
return render(request, 'orders/order/create.html', {'cart': cart, 'form':form, 'recommended_products':recommended_products})
以下 HTML 被添加到模板中,
{% if recommended_products %}
<div class="recommendations">
<h3>{% trans "People who bought this also bought" %}</h3>
{% for p in recommended_products %}
<div class="item">
<a href="{{ p.get_absolute_url }}">
<img src="{% if p.image %}{{ p.image.url }}{% else %}{%static "img/no_image.png" %}{% endif %}">
</a>
<p><a href="{{ p.get_absolute_url }}">{{ p.name }}</a></p>
</div>
{% endfor %}
</div>
{% endif %}
【问题讨论】:
-
您是否尝试过调试或在某些时候添加一些打印?
-
我已经学习了这门课程,但遇到了问题!当我选择每个产品时,它只建议第一个产品,即使我选择了第一个产品!我认为这是因为Recommender.py 中的这一行:suggestions = r.zrange(self.get_product_key(product_ids[0]), 0, -1, desc=True)[:max_results] 你收到的建议正确吗?你能帮我解决这个问题吗?
标签: django python-2.7 redis recommendation-engine