djangoプロジェクト開発のcartページ
cartページ
1.カートページ追加商品
私たちがappで商品を購入するのは、まず商品ページで商品を選んでカートに追加し、カートから決済して、この機能をどのように実現するかを考えています.
1.1表の関連付け
商品、カート、ユーザー間は、表の関連に変換することができ、カートは関係表の役割に相当し、ユーザーと商品の間には多対多の関係となる.まずmodelsに行きます.pyカートの模型を書く
新しいバージョンのdjangoでは、外部キーにon_を追加する必要があります.delete=models.CASCADEプロパティです.そうしないと、エラーが発生します.外部キーはユーザと商品に関連付けられ,カスケード削除を採用し,カートから削除されるとユーザも関連情報を削除する.データ移行を実行します.
1.2商品IDを取得し、数量num
カートをクリックすると、クリックイベントが追加され、このイベントはajaxリクエストを開始し、jsを通じてgoodsidをバックグラウンドに伝え、
market.js
1.3商品idとnumをバックグラウンドに転送する
上記の手順で商品のidとnumを取り、ajaxを使用してバックグラウンドに転送します.まず/sxw/addtocart/function(data)にデータを転送するのは、ajaxリクエストが開始された後、バックグラウンドでリクエストを受信すると、この関数をアクティブに呼び出し、データをdataに格納する役割を果たすコールバック関数です.ビュー関数を書きます.ajaxリクエストなので、jsonに戻ったほうがいいです.
最後にurlを追加
1.4カートから商品を取り除く
カートから商品を除去する方法は追加と同じです.market.js
ビュー関数
ルーティングの設定
2カートページ
2.1 cartビュー関数およびページ
cart.html
2.2カートの状態変更
カート全選
ショッピングカートのデフォルト状態の全選択ボタンが選択され、内部のすべての商品が選択されます.全選ボタンが選択されていない場合、内部商品に選択されていないものがあれば、全選は選択されていないはずです.全選択をクリックすると、元の状態が選択され、全選択とすべての商品が選択されていません.元の状態は未選択で、全選とすべての商品が選択になって単一の商品をクリックして、商品は選択から未選択になって、全選は必ず未選択になります;商品が選択されていないものから選択されている場合、すべての選択のデフォルト状態は選択されていないか、選択されている可能性があります.
カートはまた、選択した商品の数と価格に基づいて、自動的に注文総額を計算するはずです.
views_helpsに商品の総価格を計算する関数を書きます
cart.js
views.py
ルーティングの設定
3登録検出ミドルウェア
ユーザーログインを必要としないページもあれば、ユーザーログインを必要とするページもあります.毎回ユーザーがログインしているかどうかを判断すると、コード量が大きいだけでなく、結合性も低いです.インプリメンテーション機能のたびに、ユーザーがログインしているかどうかを判断するために、ミドルウェアを使用して、どのページにログインする必要があるかを選択できます.もちろん、アクセサリーも使えます.
ここではlogincheckmiddlewareを作成します.py
ミドルウェアを作成し、settingsに登録します.
1.カートページ追加商品
私たちがappで商品を購入するのは、まず商品ページで商品を選んでカートに追加し、カートから決済して、この機能をどのように実現するかを考えています.
1.1表の関連付け
商品、カート、ユーザー間は、表の関連に変換することができ、カートは関係表の役割に相当し、ユーザーと商品の間には多対多の関係となる.まずmodelsに行きます.pyカートの模型を書く
class Cart(models.Model):
c_user=models.ForeignKey(User)
c_goods=models.ForeignKey(Goods)
c_goods_num=models.IntegerField(default=1)
c_is_select=models.BooleanField(default=True)
class Meta:
db_table = 'sxw_cart'
新しいバージョンのdjangoでは、外部キーにon_を追加する必要があります.delete=models.CASCADEプロパティです.そうしないと、エラーが発生します.外部キーはユーザと商品に関連付けられ,カスケード削除を採用し,カートから削除されるとユーザも関連情報を削除する.データ移行を実行します.
1.2商品IDを取得し、数量num
カートをクリックすると、クリックイベントが追加され、このイベントはajaxリクエストを開始し、jsを通じてgoodsidをバックグラウンドに伝え、
market.js
$(".addShopping").click(function(){
console.log('add');
var $add=$(this);
var goodsid=$add.attr('goodsid');
$.get('/sxw/addtocart/',{
'goodsid':goodsid},function(data){
console.log(data);
if (data['status'] === 302){
window.open('/sxw/login/',target="_self");
}else if(data['status']===200){
$add.prev('span').html(data['c_goods_num']);
}
})
})
1.3商品idとnumをバックグラウンドに転送する
上記の手順で商品のidとnumを取り、ajaxを使用してバックグラウンドに転送します.まず/sxw/addtocart/function(data)にデータを転送するのは、ajaxリクエストが開始された後、バックグラウンドでリクエストを受信すると、この関数をアクティブに呼び出し、データをdataに格納する役割を果たすコールバック関数です.ビュー関数を書きます.ajaxリクエストなので、jsonに戻ったほうがいいです.
def add_to_cart(request):
goodsid=request.GET.get('goodsid')
# id, id,
carts=Cart.objects.filter(c_user=request.user).filter(c_goods_id=goodsid)
# , 1; , id
if carts.exists():
cart_obj=carts.first()
cart_obj.c_goods_num = cart_obj.c_goods_num + 1
else:
cart_obj=Cart()
cart_obj.c_goods_id=goodsid
cart_obj.c_user=request.user
cart_obj.save()
data={
'status':200,
'msg':'add success',
'c_goods_num':cart_obj.c_goods_num
}
#
return JsonResponse(data=data)
最後にurlを追加
url(r'^addtocart/',views.add_to_cart,name='add_to_cart'),
1.4カートから商品を取り除く
カートから商品を除去する方法は追加と同じです.market.js
$(".subShopping").click(function(){
console.log('sub');
var $sub=$(this);
var goodsid=$sub.attr('goodsid');
$.get('/sxw/subtocart/',{
'goodsid':goodsid},function(data){
console.log(data);
if (data['status'] === 302){
window.open('/sxw/login/',target="_self");
}else if(data['status']===200){
$sub.prev('span').html(data['c_goods_num']);
}
})
})
ビュー関数
def sub_to_cart(request):
goodsid = request.GET.get('goodsid')
carts = Cart.objects.filter(c_user=request.user).filter(c_goods_id=goodsid)
data = {
'status': 200,
'msg': 'add success',
}
if carts.exists():
cart_obj = carts.first()
if cart_obj.c_goods_num > 1:
cart_obj.c_goods_num = cart_obj.c_goods_num - 1
cart_obj.save()
data['c_goods_num'] = cart_obj.c_goods_num
else:
cart_obj.delete()
data['c_goods_num'] = 0
return JsonResponse(data=data)
ルーティングの設定
url(r'^subtocart/',views.sub_to_cart,name='sub_to_cart'),
2カートページ
2.1 cartビュー関数およびページ
def cart(request):
carts=Cart.objects.filter(c_user=request.user)
is_all_select= not carts.filter(c_is_select=False).exists()
data={
'title':' ',
'carts':carts,
'is_all_select':is_all_select,
'total_price':get_total_price()
}
return render(request,'cart.html',context=data)
cart.html
{
% extends 'base_main.html' %}
{
% load static %}
{
% block ext_css %}
{
{
block.super }}
<link rel="stylesheet" href="{% static 'main/css/cart.css' %}">
{
% endblock %}
{
% block ext_js %}
{
{
block.super }}
<script type="text/javascript" src="{% static 'main/js/cart.js'%}"></script>
{
% endblock%}
{
% block content %}
<div id="cart">
<h3> </h3>
<div class="full">
<section>
<ul>
<li> :aimo</li>
<li> :110</li>
<li> : </li>
</ul>
<section class="bill">
<p> </p>
<p>¥0 ,22:00 ¥30 </p>
<a href="#"> </a>
</section>
<section class="delivery">
<span> </span>
<span> </span>
<a href="#"> ></a>
</section>
<section class="delivery">
<span> </span> <input type="text" placeholder=" 100 "/>
</section>
<ul>
{
% for cart in carts %}
<li class="menulist" cartid="{
{ cart.id }}">
<div class="confirm">
<span>
{
% if cart.c_is_select %}
<span>√</span>
{
% else %}
<span></span>
{
% endif %}
</span>
</div>
<a href="#">
<img src="{
{ cart.c_goods.productimg }}" alt="{
{cart.c_goods.productlongname}}">
<p>{
{
cart.c_goods.productlongname }}</p>
<p class="presentPrice">{
{
cart.c_goods.price}}</p>
</a>
<section>
<button class="subShopping">-</button>
<span>{
{
cart.c_goods_num}}</span>
<button class="addShopping">+</button>
</section>
</li>
{
% endfor%}
</ul>
<li class="payTheBill">
<div class="all_select">
<span>
{
% if is_all_select %}
<span>√</span>
{
% else %}
<span></span>
{
% endif %}
</span>
</div>
<p>
<span> </span>
<span> :</span>
<span id="total_price">{
{
total_price}}</span>
</p>
<span id="make_order"> </span>
</li>
</section>
</div>
</div>
{
% endblock %}
2.2カートの状態変更
カート全選
ショッピングカートのデフォルト状態の全選択ボタンが選択され、内部のすべての商品が選択されます.全選ボタンが選択されていない場合、内部商品に選択されていないものがあれば、全選は選択されていないはずです.全選択をクリックすると、元の状態が選択され、全選択とすべての商品が選択されていません.元の状態は未選択で、全選とすべての商品が選択になって単一の商品をクリックして、商品は選択から未選択になって、全選は必ず未選択になります;商品が選択されていないものから選択されている場合、すべての選択のデフォルト状態は選択されていないか、選択されている可能性があります.
カートはまた、選択した商品の数と価格に基づいて、自動的に注文総額を計算するはずです.
views_helpsに商品の総価格を計算する関数を書きます
def get_total_price():
carts=Cart.objects.filter(c_is_select=True)
total=0
for cart in carts:
total += cart.c_goods_num * cart.c_goods.price
total=float('%.2f'%total)
return total
cart.js
$(function (){
$(".confirm").click(function(){
console.log("change state");
var $confirm=$(this);
var $li=$confirm.parents("li");
var cartid=$li.attr('cartid');
$.getJSON("/sxw/changecartstate/",{
'cartid':cartid},function (data){
console.log(data);
if (data['status']===200){
$("#total_price").html(data['total_price']);
if(data['c_is_select']){
$confirm.find("span").find("span").html("√");
}else{
$confirm.find("span").find("span").html("");
}
if (data['is_all_select']){
$(".all_select span span").html("√");
}else{
$(".all_select span span").html("");
}
}
})
})
$(".subShopping").click(function(){
var $sub=$(this);
var $li =$sub.parents("li");
var cartid=$li.attr("cartid");
$.getJSON("/sxw/subshopping/",{
"cartid":cartid},function(data){
console.log(data);
if (data['status']===200){
$("#total_price").html(data['total_price']);
if (data['c_goods_num']>0){
var $span =$sub.next("span");
$span.html(data['c_goods_num']);
}else{
$li.remove();
}
}
})
})
$(".all_select").click(function(){
var $all_select=$(this);
var select_list=[];
var unselect_list=[];
$(".confirm").each(function(){
var $confirm=$(this);
var cartid =$confirm.parents("li").attr("cartid");
if($confirm.find("span").find("span").html().trim()){
select_list.push(cartid);
}else{
unselect_list.push(cartid);
}
})
console.log(select_list);
console.log(unselect_list);
if(unselect_list.length > 0 ){
$.getJSON('/sxw/allselect/',{
'cart_list':unselect_list.join('#')},function(data){
console.log(data);
if(data['status']===200){
$(".confirm").find("span").find("span").html("√");
$all_select.find("span").find("span").html("√");
$("#total_price").html(data['total_price']);
}
})
}else{
if (select_list.length > 0){
$.getJSON('/sxw/allselect/',{
'cart_list':select_list.join('#')},function(data){
console.log(data);
if(data['status']===200){
$(".confirm").find("span").find("span").html("");
$all_select.find("span").find("span").html("");
$("#total_price").html(data['total_price']);
}
})
}
}
})
views.py
def change_cart_state(request):
cart_id=request.GET.get('cartid')
cart_obj=Cart.objects.get(pk=cart_id)
cart_obj.c_is_select=not cart_obj.c_is_select
cart_obj.save()
is_all_select=not Cart.objects.filter(c_user=request.user).filter(c_is_select=False).exists()
data={
'status':200,
'msg':'change ok',
'c_is_select':cart_obj.c_is_select,
'is_all_select':is_all_select,
'total_price': get_total_price(),
}
return JsonResponse(data=data)
def sub_shopping(request):
cart_id = request.GET.get('cartid')
cart_obj = Cart.objects.get(pk=cart_id)
data = {
'status':200,
'msg':'ok',
}
if cart_obj.c_goods_num > 1:
cart_obj.c_goods_num = cart_obj.c_goods_num - 1
cart_obj.save()
data['c_goods_num']=cart_obj.c_goods_num
else:
cart_obj.delete()
data['c_goods_num']=0
data['total_price'] = get_total_price()
return JsonResponse(data=data)
def all_select(request):
cart_list=request.GET.get('cart_list')
cart_list=cart_list.split('#')
carts=Cart.objects.filter(id__in=cart_list)
for cart_obj in carts:
cart_obj.c_is_select = not cart_obj.c_is_select
cart_obj.save()
print(cart_list)
data={
'status':200,
'msg':'ok',
'total_price':get_total_price(),
}
return JsonResponse(data=data)
ルーティングの設定
url(r'^changecartstate/',views.change_cart_state,name='change_cart_state'),
url(r'^subshopping/',views.sub_shopping,name='sub_shopping'),
url(r'^allselect/',views.all_select,name='all_select'),
3登録検出ミドルウェア
ユーザーログインを必要としないページもあれば、ユーザーログインを必要とするページもあります.毎回ユーザーがログインしているかどうかを判断すると、コード量が大きいだけでなく、結合性も低いです.インプリメンテーション機能のたびに、ユーザーがログインしているかどうかを判断するために、ミドルウェアを使用して、どのページにログインする必要があるかを選択できます.もちろん、アクセサリーも使えます.
ここではlogincheckmiddlewareを作成します.py
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
from App.models import User
REQUIRE_LOGIN=[
'/sxw/cart/',
'/sxw/orderdetail/',
'/sxw/orderlistnotpay/',
]
REQUIRE_LOGIN_JSON=[
'/sxw/addtocart/',
'/sxw/changecartstate/',
'/sxw/makeorder/',
]
class LoginMiddleware(MiddlewareMixin):
def process_request(self,request):
if request.path in REQUIRE_LOGIN_JSON:
user_id=request.session.get('user_id')
if user_id:
try:
user=User.objects.get(pk=user_id)
request.user=user
except:
data={
'status':301,
'msg':'user not avaliable'
}
return JsonResponse(data=data)
#return redirect(reverse('sxw:login'))
else:
data = {
'status': 301,
'msg': 'user not login'
}
return JsonResponse(data=data)
#return redirect(reverse('sxw:login'))
if request.path in REQUIRE_LOGIN:
user_id = request.session.get('user_id')
if user_id:
try:
user = User.objects.get(pk=user_id)
request.user = user
except:
return redirect(reverse('sxw:login'))
else:
return redirect(reverse('sxw:login'))
ミドルウェアを作成し、settingsに登録します.