Rental Bicycle App: Update/Delete Data

នៅ​ក្នុង​វិស័យ web development ពាក្យ​ថា «CRUD» គឺ​ជា​អក្សរ​កាត់​មក​ពី​ពាក្យ​ថា Create, Read, Update, Delete ដែល​ជា​លក្ខណៈ​សំគាល់​ web application ដ៏​ពេញ​លក្ខណៈ​ទាំងឡាយ​ណា ដែល​មាន​សមត្ថភាព​អនុញ្ញាត​អោយ​អ្នក​ប្រើប្រាស់​អាច​បង្កើត​ទិន្នន័យ (Create) ស្រង់​យក​ទិន្នន័យ (Read) កែប្រែ​ទិន្នន័យ (Update) និង​អាច​លុប​ទិន្នន័យ​ទាំងនោះ​ (Delete) ។

ដោយឡែក កន្លង​មក កម្មវិធី Rental Bicycle App ត្រូវ​បាន​បំពាក់​មុខងារ​ពីរ​រួច​ទៅ​ហើយ គឺ​មុខងារ Create និង​មុខងារ Read ។ កូដ​ខាង​ក្រោម​នេះ គឺ​ជា​ការបំពាក់​មុខ​ងារ​ពីរ​ទៀត​អោយ​កម្មិវធី Rental Bicycle App ដើម្បី​អោយ​វា​មាន​លក្ខណៈ​ជា web application ប្រដាប់​ដោយ​មុខងារ CRUD ។

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#\controllers\bikeform.py
import config, re
from bottle import template, route, request, redirect
from models import bicycledb
 
@route("/bikeform")
def renderForm():
  if 'rowedit' in config.kargs:
    del config.kargs['rowedit']
     
  return template('bikeform', data=config.kargs)
 
@route("/bikeform/edit/<id:int>")
def editForm(id):
  config.kargs['rowedit'] = bicycledb.edit(id)
  config.kargs['id'] = id
  return template('bikeform', data=config.kargs)
 
@route("/bikeform/delete/<id:int>")
def deleteForm(id):
  config.kargs['id'] = id
  bicycledb.delete(id)
  redirect('/')
 
@route("/bikeform", method="POST")
def getFormData():
  brand = request.forms.get("fbrand")
  country = request.forms.get("fcountry")
  year = request.forms.get("fyear")
  amount = request.forms.get("famount")
  price = request.forms.get("fprice")
 
  if not re.findall("[a-zA-Z]", country):
    config.kargs['message'] = "Country name could contain only letter."
    return template('bikeform', data=config.kargs)
 
  elif not (re.findall("[0-9]", year) and re.findall("[0-9]", amount)):
    config.kargs['message'] = "Year and amount must be whole number."
    return template('bikeform', data=config.kargs)
 
  elif not (re.findall(r"[-+]?\d*\.\d+|\d+", price)):
    config.kargs['message'] = "Price must be a number."
    return template('bikeform', data=config.kargs)
 
  else:
    if 'rowedit' in config.kargs:
      bicycledb.update(brand, country, int(year), int(amount), float(price), config.kargs['id'])
      del config.kargs['rowedit']
      redirect('/')
 
    else:
      bicycledb.insert(brand, country, int(year), int(amount), float(price))
      return template('bikeform', data=config.kargs)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#\models\bicycledb.py
import sqlite3
 
def insert(*bicycle):
  conn = sqlite3.connect('sqlite.db')
  cursor = conn.cursor()
 
  sql ='''CREATE TABLE IF NOT EXISTS BICYCLE(
    BRAND TEXT,
    COUNTRY TEXT,
    YEAR INT,
    AMOUNT INT,
    PRICE FLOAT
  )
  '''
 
  cursor.execute(sql)
 
  cursor.execute("INSERT INTO BICYCLE VALUES (?, ?, ?, ?, ?)", bicycle)
   
  conn.commit()
  conn.close()
 
 
def select():
  conn = sqlite3.connect('sqlite.db')
  conn.execute("VACUUM")
  cursor = conn.cursor()
 
  sql ='''CREATE TABLE IF NOT EXISTS BICYCLE(
    BRAND TEXT,
    COUNTRY TEXT,
    YEAR INT,
    AMOUNT INT,
    PRICE FLOAT
  )
  '''
 
  cursor.execute(sql)
 
  cursor.execute("SELECT * from BICYCLE")
 
  bicycles = cursor.fetchall()
   
  conn.commit()
  conn.close()
 
  return bicycles
 
def edit(id):
  conn = sqlite3.connect('sqlite.db')
  cursor = conn.cursor()
 
  cursor.execute("SELECT * from BICYCLE WHERE ROWID = " + str(id))
 
  bicycle = cursor.fetchone()
   
  conn.commit()
  conn.close()
 
  return bicycle
 
 
def update(*args):
  conn = sqlite3.connect('sqlite.db')
  cursor = conn.cursor()
 
  sql = "UPDATE BICYCLE SET BRAND=?, COUNTRY=?, YEAR=?, AMOUNT=?, PRICE=? WHERE ROWID=?"
   
  cursor.execute(sql, args)
   
  conn.commit()
  conn.close()
 
def delete(id):
  conn = sqlite3.connect('sqlite.db')
  cursor = conn.cursor()
 
  cursor.execute("DELETE FROM BICYCLE WHERE ROWID=?", (id,))
 
  conn.commit()
  conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!--\views\bikeform.tpl-->
 
%include("./partials/header.tpl")
 
<style>
#bikeform{
  margin-top: 30px;
  width: 30%;
  display: grid;
  grid-template-columns: auto calc(85% - 5px);
  grid-gap: 5px;
}
#bikeform a{
  text-align: right;
}
</style>
 
<div class="main" id="main">
  <div class="content" id="content">
    <span>BICYCLE ENTRY FORM</span>
    %if 'rowedit' in data:
    <form id="bikeform" method="POST" action="/bikeform" onsubmit="return bicycle.bicycleForm('bikeform')">
      <a>Brand:</a><input name="fbrand" value="{{data['rowedit'][0]}}" type="text" required="">
      <a>Country:</a><input name="fcountry" value="{{data['rowedit'][1]}}" type="text" required="">
      <a>Year:</a><input name="fyear" value="{{data['rowedit'][2]}}" type="text" required="">
      <a>Amount:</a><input name="famount" value="{{data['rowedit'][3]}}" type="text" required="">
      <a>Price:</a><input name="fprice" value="{{data['rowedit'][4]}}" type="text" required="">
      <a></a><input type="submit">
    </form>
    %else:
    <form id="bikeform" method="POST" action="/bikeform" onsubmit="return bicycle.bicycleForm('bikeform')">
      <a>Brand:</a><input name="fbrand" type="text" required="">
      <a>Country:</a><input name="fcountry" type="text" required="">
      <a>Year:</a><input name="fyear" type="text" required="">
      <a>Amount:</a><input name="famount" type="text" required="">
      <a>Price:</a><input name="fprice" type="text" required="">
      <a></a><input type="submit">
    </form>
    %end
    <p>{{data['message']}}</p>
    %data['message'] = ""
  </div><!--content-->
 
</div><!--main-->
 
%include("./partials/footer")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#\app.py
import os, json, config
from bottle import route, run
from controllers import index, bikeform
from public import setup
from models import bicycledb
   
@route('/')
def main():
  config.kargs['bicycles'] = json.dumps(bicycledb.select())
  return index.render(config.kargs)
   
if 'DYNO' in os.environ:
  run(host='0.0.0.0', port=os.environ.get('PORT', 9000))
else:
  run(host='localhost', port=9000, debug=True, reloader=True)

GitHub: https://github.com/Sokhavuth/Rental-Bicycle-App
Heroku: https://khmerweb-rba.herokuapp.com/