Django Models in E-Commerce Website Development

假設(shè)我們有個(gè)電商網(wǎng)站,一個(gè)基本的流程就是用戶下單,然后進(jìn)入購(gòu)物車cart, 然后進(jìn)入checkout。 假設(shè)我們有如下比較簡(jiǎn)單的Data Structure:

簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)

1.針對(duì)這個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)build data model:

models.py in the 'store' app

from django.db import models
from django.contrib.auth.models import User
# Create your models here.


class Customer(models.Model):
    user = models.OneToOneField(
        User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)

    def __str__(self):
        return self.name


class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    price = models.FloatField()
    digital = models.BooleanField(default=False, null=True, blank=False)
    image = models.ImageField(null=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def imageURL(self):
        try:
            url = self.image.url
        except:
            url = ""
        return url


class Order(models.Model):
    customer = models.ForeignKey(
        Customer, on_delete=models.SET_NULL, null=True, blank=True)
    date_ordered = models.DateTimeField(auto_now_add=True)
    complete = models.BooleanField(default=False, null=True, blank=False)
    transaction_id = models.CharField(max_length=200, null=True)

    def __str__(self):
        return str(self.id)

    @property
    def get_cart_total(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.get_total for item in orderitems])
        return total

    @property
    def get_cart_items_quantity(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.quantity for item in orderitems])
        return total


class OrderItem(models.Model):
    product = models.ForeignKey(
        Product, on_delete=models.SET_NULL, null=True, blank=True)
    order = models.ForeignKey(
        Order, on_delete=models.SET_NULL, null=True, blank=True)
    quantity = models.IntegerField(default=0, null=True, blank=True)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.product.name)

    @property
    def get_total(self):
        total = self.product.price * self.quantity
        return total


class ShippingAddress(models.Model):
    customer = models.ForeignKey(
        Customer, on_delete=models.SET_NULL, null=True, blank=True)
    order = models.ForeignKey(
        Order, on_delete=models.SET_NULL, null=True, blank=True)
    address = models.CharField(max_length=200, null=True)
    city = models.CharField(max_length=200, null=True)
    state = models.CharField(max_length=200, null=True)
    zipcode = models.CharField(max_length=200, null=True)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.address

注意下其中的image這個(gè)需要安裝pillow

pipenv install pillow

2.model需要進(jìn)行makingmigrations這樣就會(huì)創(chuàng)建Customer, Order...這些不同的models

python manage.py makingmigrations 

然后進(jìn)行migrate

python manage.py migrate

這樣就算把Data Structure建立好了,如果DB有實(shí)際的數(shù)據(jù)的話,一個(gè)簡(jiǎn)單的訪問(wèn)數(shù)據(jù)的方式就是Order.objects.all()或者Product.objects.all()

3. 把這些model加到admin后臺(tái)以準(zhǔn)備手動(dòng)添加數(shù)據(jù):

admin.py

from django.contrib import admin


# Register your models here.
from .models import *

admin.site.register(Customer)
admin.site.register(Product)
admin.site.register(Order)
admin.site.register(OrderItem)
admin.site.register(ShippingAddress)

4. 創(chuàng)建超級(jí)用戶來(lái)手動(dòng)添加數(shù)據(jù)

python manage.py createsuperuser

127.0.0.1:8000/admin 就可以訪問(wèn)了

4.1 手動(dòng)添加product, customer, order, orderitem等數(shù)據(jù)

4.2 為了給商品動(dòng)態(tài)添加圖片

采用在后臺(tái)上傳圖片的方式而不是直接在項(xiàng)目的images文件中直接添加圖片。 那么上傳的圖片你需要告訴項(xiàng)目存在項(xiàng)目的什么地方,所以需要在settings中添加:


MEDIA_URL = '/images/'

MEDIA_ROOT = os.path.join(BASE_DIR, "static/images")

然后再urls.py中添加:

from django.conf.urls.static import static
from django.conf import settings
....

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

這樣后臺(tái)upload image到對(duì)應(yīng)的product時(shí)候,系統(tǒng)會(huì)自動(dòng)將圖片添加到static/images下

5. 把添加的數(shù)據(jù)反映到網(wǎng)頁(yè)上,需要修改views.py和對(duì)應(yīng)xxx.html:

注意其中Order.objects.get_or_create(customer=customer, complete=False)的使用是根據(jù)目前還沒(méi)有結(jié)賬的該登錄用戶的信息query這個(gè)用戶的order的中item有哪些,如果沒(méi)有order就創(chuàng)建order.
items = order.orderitem_set.all() 表示用這個(gè)order去拿到所有order下的items,因?yàn)榻⒛P偷臅r(shí)候就是一個(gè)order(parent)對(duì)應(yīng)多個(gè)items(child with model 'OrderItem'), 所以這個(gè)方法其實(shí)是 parentmodel.lowercasesofchildmodel_set.all()

from django.shortcuts import render
from .models import *
# Create your views here.


def store(request):
    products = Product.objects.all()
    context = {"products": products}
    return render(request, 'store/store.html', context)


def cart(request):

    # user has logged in:
    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(
            customer=customer, complete=False)
        items = order.orderitem_set.all()

    # user has not logged in:
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items_quantity': 0}

    context = {"items": items, "order_of_this_transaction": order}
    print("context:")
    print(context)
    return render(request, 'store/cart.html', context)


def checkout(request):

    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(
            customer=customer, complete=False)
        items = order.orderitem_set.all()

    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items_quantity': 0}

    context = {"items": items, "order_of_this_transaction": order}
    return render(request, 'store/checkout.html', context)

把這些拿到的值拿去render對(duì)應(yīng)html文件的方式就是用
context = {a_key_belonging_to_some_model: value}
然后傳入context, html文件取這些值的方式就是{{a_key_belonging_to_some_model.xxx}},比如item對(duì)應(yīng)的model就是orderitem, 里面有成員quantity, 所以直接item.quantity就可以拿到這個(gè)物品的數(shù)量。orderitem有外鍵product, 而product這個(gè)model有成員name,所以item.product.name可以拿到這個(gè)item對(duì)應(yīng)的product的name.

item.get_total的用法其實(shí)是在models.py里面用了python的property decorator, 關(guān)于為什么要用property decorator,這里有篇不錯(cuò)的文章做了解釋.

比如下面就是在cart.html中的render出數(shù)據(jù)的一段代碼:

{% for item in items %}
  <div class="row cart-row align-items-center">
    <div class="col-lg-3">
      <img class="row-image" src="{{item.product.imageURL}}" alt="" />
    </div>
    <div class="col-lg-3 table-content">{{item.product.name}}</div>
    <div class="col-lg-2 table-content">
      SEK {{item.product.price|floatformat:2}}
    </div>
    <div class="col-lg-2 table-content quantity-container">
      <div class="quantity">
        <img
          src="{% static 'images/up-arrow.png' %}"
          alt=""
          class="chg-quantity"
        />
        <img
          src="{% static 'images/down-arrow.png' %}"
          alt=""
          class="chg-quantity"
        />
      </div>
      <p class="quantity">
        {{item.quantity}}
      </p>
    </div>
    <div class="col-lg-2 table-content">
      <span>SEK {{ item.get_total }}</span>
    </div>
  </div>
  {% endfor %}
</div>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容