日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

05 商品模块

發(fā)布時間:2025/3/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 05 商品模块 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

商品主頁頁面

商品主頁頁面的前端頁面 效果圖如下:

?

后端視圖的業(yè)務(wù)邏輯處理:

根據(jù)前端展示的頁面,后端需要向前端傳送的數(shù)據(jù)有:

  1 后端需要想前端傳送的數(shù)據(jù)有
  2 全部商品額分類信息
  3 輪播圖的數(shù)據(jù)
  4 廣告的信息
  5 分類商品展示的標(biāo)題和圖片
  6 用戶購物車的信息

視圖 IndexView 函數(shù)的代碼如下:

from django.shortcuts import render from django.views.generic import View from .models import GoodsCategory,IndexGoodsBanner,IndexPromotionBanner from .models import IndexCategoryGoodsBannerclass IndexView(View):def get(self,request):# 后端需要想前端傳送的數(shù)據(jù)有# 全部商品額分類信息# 輪播圖的數(shù)據(jù)# 廣告的信息# 分類商品展示的標(biāo)題和圖片# 用戶購物車的信息# 獲取所有的商品分類goods_cate=GoodsCategory.objects.all()# 獲取輪播圖信息index_banner = IndexGoodsBanner.objects.all().order_by("index")# 獲取廣告的信息promotinon_banners=IndexPromotionBanner.objects.all().order_by("index")for category in goods_cate:# 主頁分類商品的標(biāo)題category_title=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=0)[:4]category.title = category_titlecategory_image=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=1)[:4]category.img = category_image# 先把購物車的數(shù)量 設(shè)置為0cart_num = 0context = {"goods_cate":goods_cate,"index_banners":index_banner,"promotinon_banners":promotinon_banners,"cart_num":cart_num}return render(request,'index.html',context) View Code

?

前端模板商品分類要填充的代碼如下:

<ul class="subnav fl">{% for cate in goods_cate %}<li><a href="#model0{{ forloop.counter }}" class="{{ cate.logo }}">{{ cate.name }}</a></li>{% endfor %} </ul> View Code

?

前端模板輪播圖要填充的代碼如下: 

<ul class="slide_pics">{% for slide in index_banners %}<li><a href="#"><img src="{{ slide.image.url }}" alt="幻燈片"></a></li>{% endfor %}</ul> View Code

?

前端模板活動廣告要填充的代碼如下:

<div class="adv fl">{% for add in promotinon_banners %}<a href="{{ add.url }}"><img src="{{ add.image.url }}"></a>{% endfor %}</div> View Code

?

前端模板商品分類展示要填充的代碼如下:

{% for cate in goods_cate %}<div class="list_model"><div class="list_title clearfix"><h3 class="fl" id="model01">{{ cate.name }}</h3><div class="subtitle fl"><span>|</span>{% for title in cate.title %}<a href="#">{{ title.sku.title }}</a>{% endfor %}</div><a href="#" class="goods_more fr" id="fruit_more">查看更多 ></a></div><div class="goods_con clearfix"><div class="goods_banner fl"><img src="{{ cate.image.url }}"></div><ul class="goods_list fl">{% for img in cate.img %}<li><h4><a href="#">{{ img.sku.name }}</a></h4><a href="#"><img src="{{ img.sku.default_image.url }}"></a><div class="prize">{{ img.sku.price }}</div></li>{% endfor %}</ul></div></div>{% endfor %} View Code

可以在前端中判斷用戶是否登陸,如果登陸出現(xiàn)歡迎訪問,沒有則是登陸和注冊

{% if user.is_authenticated %}<div class="login_btn fl">歡迎您:<em>{{ user.username }}</em><span>|</span><a href="{% url 'users:logout' %}">退出</a></div>{% else %}<div class="login_btn fl"><a href="{% url 'users:login' %}">登錄</a><span>|</span><a href="{% url 'users:register' %}">注冊</a></div> {% endif %}

在瀏覽器中輸入,就可以顯示后端填充的信息

http://127.0.0.1:8000

?頁面靜態(tài)化(重點)

把動態(tài)模板的頁面渲染一次后,把結(jié)果保存下來,存成一個靜態(tài)的html文件,就是頁面靜態(tài)化,對于不經(jīng)常變化的動態(tài)頁面可以做靜態(tài)化處理。

進(jìn)行靜態(tài)化的觸發(fā): 運(yùn)營人員修改主頁動態(tài)數(shù)據(jù)的時候,進(jìn)行靜態(tài)化處理,就是運(yùn)營人員修改數(shù)據(jù)的時候,將生成靜態(tài)化的過程交給celery異步完成,不影響任何其他業(yè)務(wù)。

在celery_tasks/tasks.py中定義生成 靜態(tài)化文件的任務(wù)

from django.core.mail import send_mail from django.conf import settings from django.template import loader from goods.models import GoodsCategory, IndexGoodsBanner, IndexPromotionBanner from goods.models import IndexCategoryGoodsBanner@app.task def generate_static_index_html():"""生成主頁的靜態(tài)html文件"""# 獲取所有的商品分類goods_cate = GoodsCategory.objects.all()# 獲取輪播圖信息index_banner = IndexGoodsBanner.objects.all().order_by("index")# 獲取廣告的信息promotinon_banners = IndexPromotionBanner.objects.all().order_by("index")for category in goods_cate:# 主頁分類商品的標(biāo)題category_title = IndexCategoryGoodsBanner.objects.filter(category=category, display_type=0)[:4]category.title = category_titlecategory_image = IndexCategoryGoodsBanner.objects.filter(category=category, display_type=1)[:4]category.img = category_image# 先把購物車的數(shù)量 設(shè)置為0cart_num = 0context = {"goods_cate": goods_cate,"index_banners": index_banner,"promotinon_banners": promotinon_banners,"cart_num": cart_num}# 加載模板template = loader.get_template("static_index.html")# 渲染模板,生成html數(shù)據(jù)html_data = template.render(context)# 保存產(chǎn)生的靜態(tài)html數(shù)據(jù)file_path = os.path.join(settings.STATICFILES_DIRS[0], "index.html")with open(file_path, "w") as f:f.write(html_data) View Code?

對以上的局部代碼進(jìn)行解釋

from django.template import loader# 加載模板template = loader.get_template("static_index.html")# 渲染模板,生成html數(shù)據(jù)html_data = template.render(context)# 保存產(chǎn)生的靜態(tài)html數(shù)據(jù)file_path = os.path.join(settings.STATICFILES_DIRS[0], "index.html")with open(file_path, "w") as f:f.write(html_data)

把模板渲染過后的數(shù)據(jù),寫入到index.html文件中,當(dāng)瀏覽器訪問主頁的時候就會返回靜態(tài)話的文件,減少服務(wù)器的壓力。

用于靜態(tài)的話的文件是給未登錄的用戶使用的,所以在templates中把index.html文件重新復(fù)制一份在當(dāng)前的目錄下,并命名為static_index.html,

把static_index.html中的判斷用戶是否登陸的代碼刪掉,只留用戶注冊的:

<div class="login_btn fl"><a href="{% url 'users:login' %}">登錄</a><span>|</span><a href="{% url 'users:register' %}">注冊</a> </div>

?

?以前的如下所示:

把當(dāng)前的項目復(fù)制到家目錄下(python)

修改nginx的配置文件

sudo vim /usr/local/nginx/conf/nginx.conf

?

?

?重啟niginx服務(wù)器

sudo /usr/local/nginx/sbin/nginx -s reload 

開啟celery服務(wù)器

cd celery -A celery_tasks.tasks worker --loglevel=info

在python manager.py shell 中測試

from celery_tasks.tasks import generate_static_index_html generate_static_index_html.delay()

celery會收到任務(wù)

?

在python/ttsx/static會生成一個index.html文件

?在瀏覽器中輸入本機(jī)的ip地址,會調(diào)用靜態(tài)化的文件

http://192.168.228.135/

?

?

把django中動態(tài)處理的頁面和nginx的靜態(tài)頁面區(qū)分開來,所以把商品頁的路徑改成另外一個:

url(r'^index$',views.IndexView.as_view(),name='index')

?

通過改寫admin的管理類調(diào)用生成靜態(tài)頁面的異步任務(wù)

當(dāng)運(yùn)營人員對模型類,進(jìn)行添加和修改的時候就會觸發(fā)celery的任務(wù)生成靜態(tài)的話的文件

通過添加save_model 和delete_model的方法,只要一觸發(fā)就會調(diào)用celery

在gooods應(yīng)用中的admin中添加管理器的方法;

from django.contrib import adminfrom goods.models import IndexGoodsBanner, IndexCategoryGoodsBanner, IndexPromotionBanner from goods.models import GoodsCategory from celery_tasks.tasks import generate_static_index_htmlclass BaseModel(admin.ModelAdmin):def save_model(self, request, obj, form, change):obj.save()generate_static_index_html.delay()def delete_model(self, request, obj):"""admin站點在模型刪除數(shù)據(jù)的時候調(diào)用"""# 從數(shù)據(jù)庫中刪除 obj.delete()# 調(diào)用生成靜態(tài)頁面的celery異步任務(wù) generate_static_index_html.delay()class IndexPromotionBannerAdmin(BaseModel):pass class GoodsCategoryAdmin(BaseModel):"""商品分類信息的管理類"""# 在這里填充控制amdin站點的展示效果passadmin.site.register(IndexPromotionBanner,IndexPromotionBannerAdmin) admin.site.register(GoodsCategory, GoodsCategoryAdmin) View Code

?

在后臺管理頁面把主頁促銷活動的盛夏的順序改為2,保存

一開始的靜態(tài)化的順序

觸發(fā)celery生成靜態(tài)化的順序

使用緩存(重點)

把備份的數(shù)據(jù)放到內(nèi)存中,如果下次訪問的時候,如果內(nèi)存中有就從內(nèi)存中獲取,如果內(nèi)存中沒有則django動態(tài)的計算數(shù)據(jù),然后在設(shè)置到緩存中供下次使用

django關(guān)于緩存的文檔:http://python.usyiyi.cn/translate/django_182/topics/cache.html

這里我使用的是,訪問緩存

你可以通過 類字典對象django.core.cache.caches.訪問配置在CACHES?設(shè)置中的字典類對象

最基本的接口是?set(key,?value,?timeout)?和?get(key):

get(key) 如果沒有取到值則會返回None

from django.core.cache import cache >>> cache.set('my_key', 'hello, world!', 30) >>> cache.get('my_key') 'hello, world!

在IndexView的視圖中添加緩存后的代碼如下:

from django.core.cache import cacheclass IndexView(View):def get(self,request):# 后端需要想前端傳送的數(shù)據(jù)有# 全部商品額分類信息# 輪播圖的數(shù)據(jù)# 廣告的信息# 分類商品展示的標(biāo)題和圖片# 用戶購物車的信息# 先從緩存中取數(shù)據(jù)context=cache.get("index_page_data")if context is None:print("沒有用上緩存的數(shù)據(jù),從數(shù)據(jù)庫中查詢")# 獲取所有的商品分類goods_cate=GoodsCategory.objects.all()# 獲取輪播圖信息index_banner = IndexGoodsBanner.objects.all().order_by("index")# 獲取廣告的信息promotinon_banners=IndexPromotionBanner.objects.all().order_by("index")for category in goods_cate:# 主頁分類商品的標(biāo)題category_title=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=0)[:4]category.title = category_titlecategory_image=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=1)[:4]category.img = category_imagecontext = {"goods_cate":goods_cate,"index_banners":index_banner,"promotinon_banners":promotinon_banners,}# 把數(shù)據(jù)放到緩存中cache.set('index_page_data',context,3600)# 先把購物車的數(shù)量 設(shè)置為0cart_num = 0context.update(cart_num=0)return render(request,'index.html',context) View Code

?

在redis中查詢緩存的數(shù)據(jù),第一次沒有

在瀏覽器中訪問主頁的視圖:

http://127.0.0.1:8000/index

?

在redis中查詢緩存的數(shù)據(jù),會發(fā)現(xiàn)多了一條緩存數(shù)據(jù)

設(shè)置有效期和admin管理類來維護(hù)緩存數(shù)據(jù)?

1 在更新數(shù)據(jù)庫的時候把緩存刪掉  

cash.delete("index_page_data")

2 設(shè)置緩存的有效期

cache.set("index_page_data", context, 3600)

在admin中添加刪除緩存的方法

from django.core.cache import cacheclass BaseAdmin(admin.ModelAdmin):"""admin站點的模型管理類,可以控制admin站點對于模型的展示修改等操作"""def save_model(self, request, obj, form, change):"""admin站點在模型保存數(shù)據(jù)的時候調(diào)用"""# obj是要保存的模型對象(models里的類的對象)# 將數(shù)據(jù)保存到數(shù)據(jù)庫中 obj.save()# 調(diào)用生成靜態(tài)頁面的celery異步任務(wù) generate_static_index_html.delay()# 清除主頁的緩存數(shù)據(jù)cache.delete("index_page_data")def delete_model(self, request, obj):"""admin站點在模型刪除數(shù)據(jù)的時候調(diào)用"""# 從數(shù)據(jù)庫中刪除 obj.delete()# 調(diào)用生成靜態(tài)頁面的celery異步任務(wù) generate_static_index_html.delay()# 清除主頁的緩存數(shù)據(jù)cache.delete("index_page_data") View Code

判斷用戶是否是登陸的狀態(tài),如果是,則從購物車中獲取數(shù)據(jù):

用戶購物車在redis中存入的格式是哈希類型"cart_user_id":{"鍵":"值"},商品的id當(dāng)成鍵,商品的數(shù)量當(dāng)做值

from django_redis import get_redis_connection # 用戶如果是登陸的情況從redis中獲取購物車的數(shù)量if request.user.is_authenticated():redis_con = get_redis_connection("default")# cart是一個字典對象 {"sku_1":"1",'sku_2':'3' ---}cart = redis_con.hgetall('cart_%s' % request.user.id)# 遍歷疊加for count in cart.values():cart_num += int(count)context.update(cart_num=cart_num)

?

?把以上的代碼添加到商品主頁的視圖IndexViews中:

class IndexView(View):def get(self,request):# 后端需要想前端傳送的數(shù)據(jù)有# 全部商品額分類信息# 輪播圖的數(shù)據(jù)# 廣告的信息# 分類商品展示的標(biāo)題和圖片# 用戶購物車的信息# 先從緩存中取數(shù)據(jù)context=cache.get("index_page_data")if context is None:print("沒有用上緩存的數(shù)據(jù),從數(shù)據(jù)庫中查詢")# 獲取所有的商品分類goods_cate=GoodsCategory.objects.all()# 獲取輪播圖信息index_banner = IndexGoodsBanner.objects.all().order_by("index")# 獲取廣告的信息promotinon_banners=IndexPromotionBanner.objects.all().order_by("index")for category in goods_cate:# 主頁分類商品的標(biāo)題category_title=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=0)[:4]category.title = category_titlecategory_image=IndexCategoryGoodsBanner.objects.filter(category=category,display_type=1)[:4]category.img = category_imagecontext = {"goods_cate":goods_cate,"index_banners":index_banner,"promotinon_banners":promotinon_banners,}# 把數(shù)據(jù)放到緩存中cache.set('index_page_data',context,3600)# 先把購物車的數(shù)量 設(shè)置為0cart_num = 0# 用戶如果是登陸的情況從redis中獲取購物車的數(shù)量if request.user.is_authenticated():redis_con = get_redis_connection("default")# cart是一個字典對象 {"sku_1":"1",'sku_2':'3' ---}cart = redis_con.hgetall('cart_%s' % request.user.id)# 遍歷疊加for count in cart.values():cart_num += int(count)context.update(cart_num=cart_num)return render(request,'index.html',context) View Code

商品詳情頁面視圖

商品詳情頁面的前端頁面:

?

?

根據(jù)前端的頁面后端業(yè)務(wù)邏輯如下:

  1 查詢?nèi)可唐贩诸惖男畔?br />   2 查詢商品表的信息
  3 獲取最新的推薦商品2個同類商品
  4 獲取其他規(guī)格的商品
  5 從訂單中獲取評論信息
  6 購物車數(shù)量
  7 設(shè)置用戶的瀏覽歷史的記錄

class DetailView(View):def get(self, request,sku_id):# 查詢?nèi)可唐贩诸惖男畔?/span># 查詢GoodSsku表的信息# 查詢?nèi)可唐贩诸惖男畔?/span>goods_cate =GoodsCategory.objects.all()# 查詢商品的信息try:sku = GoodsSKU.objects.get(id=sku_id)except GoodsSKU.DoesNotExist:# raise Http404('商品不存在')return redirect(reverse("goods:index"))# 獲取最新的推薦商品2個同類商品new_goods = GoodsSKU.objects.filter(category=sku.category).order_by("-create_time")[:2]# 獲取其他規(guī)格的商品goods_skus = sku.goods.goodssku_set.exclude(id=sku_id)# 從訂單中獲取評論信息sku_orders=sku.ordergoods_set.all().order_by("-create_time")[:30]if sku_orders:for sku_order in sku_orders:sku_order.create_time = sku_order.create_time.strftime("%Y-%m-%d %H-%M-%S")sku_order.username = sku_order.order.user.usernameelse:sku_orders=[]context = {"goods_cate": goods_cate,"sku": sku,"new_goods": new_goods,"goods_skus": goods_skus,"orders":sku_orders}# 購物車數(shù)量cart_num = 0# 如果是登錄的用戶if request.user.is_authenticated():user_id = request.user.id# 從redis中獲取購物車信息redis_conn = get_redis_connection("default")# 如果redis中不存在,會返回0cart = redis_conn.hgetall("cart_%s" % user_id)for val in cart.values():cart_num += int(val)# 瀏覽記錄# 移除已經(jīng)存在的本商品瀏覽記錄redis_conn.lrem("history_%s" % user_id, 0, sku_id)# 添加新的瀏覽記錄redis_conn.lpush("history_%s" % user_id, sku_id)# 只保存最多5條記錄redis_conn.ltrim("history_%s" % user_id, 0, 4)context.update({"cart_num": cart_num})return render(request,'detail.html',context) View Code

?

對上面的代碼進(jìn)行解析

添加5條最新的瀏覽歷史記錄

添加商品id的時候,先把購物車中包含本次的商品ID移除? ?(lrem("history_%s" % user_id, 0, sku_id))? 0代表刪除所有??

再把現(xiàn)在的添加進(jìn)去

通過lrim只保存5條歷史信息

# 瀏覽記錄 # 移除已經(jīng)存在的本商品瀏覽記錄 redis_conn.lrem("history_%s" % user_id, 0, sku_id) # 添加新的瀏覽記錄 redis_conn.lpush("history_%s" % user_id, sku_id) # 只保存最多5條記錄 redis_conn.ltrim("history_%s" % user_id, 0, 4)

?

把所有能改成{%url "goods:detail" sku.id%}都改成這樣的(商品詳情頁)

可以隨便點進(jìn)一個詳情頁面,然后取uers/info中去查看歷史記錄有沒有設(shè)置成功(獲取redis中查看)

為詳情的頁面設(shè)置緩存

就添加幾句代碼

class DetailView(View):def get(self, request,sku_id):# 查詢?nèi)可唐贩诸惖男畔?/span># 查詢商品表的信息# 獲取最新的推薦商品2個同類商品# 獲取其他規(guī)格的商品# 從訂單中獲取評論信息# 購物車數(shù)量# 設(shè)置用戶的瀏覽歷史的記錄context = cache.get("detail_data_%s" % requset.user.id)if context is None:goods_cate =GoodsCategory.objects.all()# 查詢商品的信息try:sku = GoodsSKU.objects.get(id=sku_id)except GoodsSKU.DoesNotExist:# raise Http404('商品不存在')return redirect(reverse("goods:index"))# 獲取最新的推薦商品2個同類商品new_goods = GoodsSKU.objects.filter(category=sku.category).order_by("-create_time")[:2]# 獲取其他規(guī)格的商品goods_skus = sku.goods.goodssku_set.exclude(id=sku_id)# 從訂單中獲取評論信息sku_orders=sku.ordergoods_set.all().order_by("-create_time")[:30]if sku_orders:for sku_order in sku_orders:sku_order.create_time = sku_order.create_time.strftime("%Y-%m-%d %H-%M-%S")sku_order.username = sku_order.order.user.usernameelse:sku_orders=[]context = {"goods_cate": goods_cate,"sku": sku,"new_goods": new_goods,"goods_skus": goods_skus,"orders":sku_orders}# 設(shè)置緩存cache.set("detail_data_%s" % requset.user.id,context,3600)# 購物車數(shù)量cart_num = 0# 如果是登錄的用戶if request.user.is_authenticated():user_id = request.user.id# 從redis中獲取購物車信息redis_conn = get_redis_connection("default")# 如果redis中不存在,會返回0cart = redis_conn.hgetall("cart_%s" % user_id)for val in cart.values():cart_num += int(val)# 瀏覽記錄# 移除已經(jīng)存在的本商品瀏覽記錄redis_conn.lrem("history_%s" % user_id, 0, sku_id)# 添加新的瀏覽記錄redis_conn.lpush("history_%s" % user_id, sku_id)# 只保存最多5條記錄redis_conn.ltrim("history_%s" % user_id, 0, 4)context.update({"cart_num": cart_num})return render(request,'detail.html',context) View Code

?

  

?

轉(zhuǎn)載于:https://www.cnblogs.com/aaronthon/p/9347818.html

總結(jié)

以上是生活随笔為你收集整理的05 商品模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。