Day15 - [丰收款] 撰写Django的Model,使用ORM和Heroku Postgres绑一起。

今天面临了断更的危机!

本人从昨晚开始肠胃不适,整晚翻来覆去无法入眠,早上更严重,请假了一整天,接着开始发烧和呕吐,下午去挂了大医院的急诊後,是急性肠胃发炎,刚刚打完点滴才回来,折腾了一整天,原本上天可能要我放弃。

不过再怎麽说都努力了一半了,虽然现在身体相当不适,一整天完全没有进食,决定还是再努力一下,中断了实在可惜。

回到正题

但在此之前,我们因为受限於Heroku的资料库限制,无法使用预设的SQLite,要先修改一下资料库设定成Postgres。我们先找到Django App mysite目录底下的settings.py,修改其中DATABASES的Dictionary物件,把原先预设的sqlite3换成postgresql。当然还要加上其他的参数,包含USERPASSWORDHOSTPORT

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'd15______rvdt',
        'USER': 'xbz______bsnz',
        'PASSWORD': 'bfbca81796d______________________d5162d1c69dc3dd9e76e5',
        'HOST': 'ec2-________-31.compute-1.amazonaws.com',
        'PORT': '5432'
    }
}

然後,我们就可以先新增一个order Django App,然後再其目录底下的models.py设定一个新的模型。

from django.db import models


class Payment(models.Model):
    order_no = models.CharField(max_length=13)
    ts_no = models.CharField(max_length=14, null=True)
    amount = models.IntegerField()
    pay_type = models.CharField(max_length=10)
    pay_status = models.CharField(max_length=20, null=True)
    pay_token = models.CharField(max_length=100, null=True)
    atm_pay_no = models.CharField(max_length=14, null=True)
    web_atm_url = models.CharField(max_length=250, null=True)
    otp_url = models.CharField(max_length=250, null=True)
    card_pay_url = models.CharField(max_length=250, null=True)
    create_time = models.DateTimeField()
    lm_time = models.DateTimeField(null=True)

    def __str__(self):
        return self.order_no
程序说明

我们在order的models.py,新增了一个Payment class,接着就要定义其中有哪些属性。这些属性均可透过models的对应方法,来定义该属性的资料型别,以及一些额外的宣告与限制。

例如:

  • 要新增一个文字类型的属性,可使用models.CharField()
  • 要新增一个整数类型的属性,可使用models.IntegerField()
  • 要新增一个时间类型的属性,可使用models.DateTimeField()
    完整的用法请参阅Django的官方文件

而我们对应到资料库中,若是希望该栏位是非NULL的话,则可在其中参数加上null=True。而若有最大长度限制,则可使用max_length来指定。

在设定完成後,因为刚刚我们已设定settings.py中的DATABASE连线资讯,因此我们可以透过manage.py的makemigrations以及migrate指令将异动更新至连结的DATABASE。

mysite > python manage.py makemigrations
mysite > python manage.py migrate

接着我们可以使用pgAdmin看看Tables里面发生了什麽神奇的事。

https://ithelp.ithome.com.tw/upload/images/20210930/20130354fPMA0p0zZX.png

可以在Shcemas > Tables底下,发现新增了一个order_payment的Table。而里面的栏位,就是依照刚刚Django Model所定义的栏位所建立的。由於我们没有新增primary_key,因此预设会新增一个id栏位作为PK。

新增一笔ATM虚拟帐户订单

我们需要先将先前产生一笔订单的零散测试用的python code,先整理到App底下,我命名为SinopacAPI.py。并在底下开一个static method,让它可以直接呼叫永丰API产生一笔订单,并且最後将解密回传後的JSON回传回来。接着就可以将其值都拿出来,产生一个新的Payment物件,把值设定好後,再善用具备ORM映射的Payment物件的.save()方法,将值写到资料库中。

在order/models.py中,扩增create_new_order():

from datetime import datetime
from django.db import models
from .sinopacapi import SinopacAPI

def create_new_order(will_paid, amount):
    resp_json = SinopacAPI.create_new_order(will_paid, amount)
    new_payment = Payment()
    new_payment.order_no = resp_json["OrderNo"]
    new_payment.ts_no = resp_json["TSNo"]
    new_payment.amount = resp_json["Amount"]
    new_payment.pay_status = resp_json["Status"]
    new_payment.atm_pay_no = resp_json["ATMParam"]["AtmPayNo"]
    new_payment.web_atm_url = resp_json["ATMParam"]["WebAtmURL"]
    new_payment.otp_url = resp_json["ATMParam"]["OtpURL"]
    new_payment.create_time = datetime.now()
    new_payment.save()

    return resp_json

而在View中,我先以最简单的方式呼叫後,在页面上会显示出这次的OrderNo。
在order/views.py的程序码

from django.http import HttpResponse
from .models import create_new_order


def create_order(request):
    will_paid = True
    amount = 799
    resp_json = create_new_order(will_paid, amount)
    print("### resp_json: {}".format(resp_json))
    return HttpResponse("New Order Created: {}".format(resp_json["OrderNo"]))

当然也需要将urls.py设定一下,以下为order/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('createorder', views.create_order, name='createorder'),
]

因此我们就可以先在本机端测试一下:
http://127.0.0.1:8000/order/createorder

https://ithelp.ithome.com.tw/upload/images/20210930/20130354iecz0zZSAe.png

接着我们再到pgAdmin中查看order_payment的资料:

https://ithelp.ithome.com.tw/upload/images/20210930/20130354BzwKhJ5Hm5.png

太感动了,我们成功运用ORM的方法,产生一笔订单了。

身体不舒服,今天只能勉强先做到这样,明天再来产生真的BackendURL给永丰作呼叫,并行来看看我们是否能成功取得PayToken。


<<:  Day15 Hook-useRef

>>:  Day 29 - Math Object & Date Object

Day 21 - Robot Return to Origin

大家好,我是毛毛。ヾ(´∀ ˋ)ノ 废话不多说开始今天的解题Day~ 657. Robot Retu...

学习Python纪录Day30

参赛心得: 今天是铁人赛最後一天,会参加铁人赛是因为学校做也得要求,虽然学习的内容不算难,主要的文章...

Day 10: 面试中成长

My TIP Re5ume 英文履历 1 通吃国内外市场 2 Content Education E...

Day 20 api介绍

到了 Odoo 8.0,引入了新API,封装在api.py文件中,主要有一下几种类型: Odoo 1...

[Day11] 文本/词表示方式(二)-BOW与TFIDF

一. BOW BOW的全名为Bag-of-words,中文是'一袋文字',意思就是将词都丢进一个袋子...