python django專案開發總結

freeman51002396發表於2017-11-17
用python django框架,參與開發了一個電商物流的專案,簡單說就是從使用者(店主)在各個電商平臺拉訂單,然後智慧選倉,傳送訂單,由倉庫出貨。
訂單後處理功能包括:各電商平臺拉取訂單,檢查訂單(去重,留言分析,貨到付款標識識別,地址合法性檢查),拆單/並單,選倉發貨。
輔助功能包括:允許開展營銷活動(滿元贈,滿件贈)。允許開啟消費者理智期(延遲處理訂單)。全國範圍智慧選倉進行備貨,業內叫分倉。
專案採用python django框架,涉及到下面幾個技術要點:
1、以外來鍵(Foreign Key)為關聯,進行前向,後向聯合查表,組合成一個QuerySet物件輸出。
   def get(self, user_id, order_id):
# filter方法,這是最常用的一個方法,用來取出資料庫中的表項,是一個list。
        order_details = OrderDetail.objects.\
            filter(order_id=order_id, is_deleted=False). \
            select_related('sku')   # select_related是後向查表,以'sku'為外來鍵的另一張子表,一併查出來。
        order_history = OrderHistory.objects.filter(order_id=order_id)
        # prefetch_related是前向查表,一併查出父表,並且可以迭加使用。
order = Order.objects.\
            prefetch_related(Prefetch('order_detail', queryset=order_details, to_attr='order_details')).\
            prefetch_related(Prefetch('order_history', queryset=order_history)).\
            select_related('store').\
            get(user_id=user_id, id=order_id)
        return order   #返回的order是一個django QuerySet物件。是組合了多張表構成的一個物件。
2、QuerySet物件可以多次條件過濾,從而支援多條件查詢操作。
# warehouse_list是一個QuerySet物件,可以經過幾個不同條件的過濾和排除,從而得到符合多條件的物件。
        if 'province' in dict_arg:
            warehouse_list = warehouse_list.filter(province__in=dict_arg['province'])
        if 'city' in dict_arg:
            warehouse_list = warehouse_list.filter(city__in=dict_arg['city'])
        if 'not_approved' in dict_arg:
            warehouse_list = warehouse_list.exclude(approved=dict_arg['not_approved'])
# province__in,資料庫列名加上__in的意思是一個條件判斷,判斷province是否在=後的列表中。這是django強大之處。
3、prefetch_related另一種經典用法,關聯表列名
        conditions = {
             "warehouseservice__code": SERVICE_ITEMS[0][0],
        }
# 'warehouseservice_set'這是warehouse的一個父表的QuerySet物件。實際上django在查表時,一併把關聯表全部查出來了的。
# 'warehouseservice__price'和"warehouseservice__code"是父表中的兩個列名:price和code。
warehouse_list = warehouse_list.prefetch_related('warehouseservice_set')
.filter(**conditions).order_by('warehouseservice__price')
4、django排序輸出
# 用order_by方法,可以對多個列名進行排序,先排第一個,第一個相同的情況下,按第二個來排。預設是升序,前面加-是降序。
warehouse_list = warehouse_list.order_by('-stars_level', 'cost_per_order')


5、http url中的query取參方法
# 前端用GET或POST方法提交時,都可以在http url中新增query引數,就是?type=1這種引數。
request.GET 類似於一個字典,更好的辦法是用 request.GET.get('a', 0) 當沒有傳遞 a 的時候預設 a 為 0
一個同事寫了一個get_param_by_request(params, param_name, default_val=None, _type=None)方法來達到這個目的,
看來似乎沒必要。


6、url正規表示式寫法
django框架給出了一個
urlpatterns = [
    # 建立直播頻道、啟動/停止直播
    url(r'^create$', livechat_view.create, name='create_channel'),


    # 傳送申請看倉訊息
    url(r'^requests$', livechat_view.requests, name='create_or_list_requests'),


    # idx是頻道號,func是動作名。這兩個引數都通過url給進來。這是一個技巧。
    url(r'^(?P<idx>\w+)/(?P<func>\w+)$', livechat_view.handle, name='pause_resume_delete'),
]
django的匹配url時,是從上到下來順序執行的,如果我們把最後一行提到最前面,那建立頻道和傳送看倉訊息就得不到正確的匹配。


7、前後臺引數傳遞,用code而不是值,前端要展示的值,由後端查出來給前端。
OPERATION_CODE = (
    (10, '建立訂單', '接收訂單'),
    (11, '訂單稽核成功', '訂單通過系統稽核'),


    (30, '倉庫接單', '倉庫成功接受發貨任務'),
    (31, '發貨完成', '倉庫出庫完成'),
)
這個編碼值,傳遞起來簡單準確,資料量也少。當一個程式碼的描述值發生變化時,code仍然不用變。


8、基於ModelSerializer做序列化,返回json物件給前端。
class OrderHistorySerializer(ModelSerializer):
    order_id = CharField(source='order.id')
    class Meta:
        model = OrderHistory
        fields = [
            'id', 'created_at', 'updated_at', 'order_id', 'is_system',
            'operator_id', 'copy_operator_name', 'action', 'comment',
        ]
把要返回的欄位放進去,就可以得到json化的dict返回,比較方便快捷。























相關文章