学习Django一周时间了,决定写一个简单的东西出来,碰巧最近培训班老师讲MySQL,那就写个存储相关的吧,于是定计划,做一个类似商场储物柜的小站点。商场超市都会有给顾客放东西的储物柜,点击“存包”就会生成随机条形码,然后打开一个空柜子(如果有的话),条形码仅一次有效。我做的站点最终呈现如下:

Django小型项目练习:模拟商场储物柜

1.两个表单,分别用于查询和插入数据,数据格式均为字符串类型。

2.插入数据无限制,在文本框输入要插入的数据后,点击“添加”按钮就可以讲数据插入数据库。之后会得到一个16个字符的随即字符串,后面凭借此字符串才能获得存入数据库的数据。

3.查询数据需要输入验证码,这主要是防止有人暴力查询。如上所述,存数据时生成的 key 仅仅能取出一次数据,重复使用无效。这是通过flag字段控制的,插入一条数据时,flag默认为1,取出数据后,flag置为0,表示该行数据不可取。

数据库结构如下:

Django小型项目练习:模拟商场储物柜

--

Django小型项目练习:模拟商场储物柜

这个小项目的实现也是在改来改去的过程中完成的,但是这里就不描述这个过程了,而是从整体上看如何实现之。      

---环境---

OS:kubuntu 17.04

Python:2.7

Django:1.8

---

setp1:pip install --user virtualenv 安装虚拟环境,虚拟环境中的Python包与操作系统上的Python包是隔离,虽然在我们这个项目中这不是必须的,但是有时候虚拟环境就会很有用,比如我们我们要使用不同版本的Django,就可以把他们放到不同的虚拟环境中了。

setp2:cd ~/my_python/ 进入~/my_python,然后执行 virtualenv my_env --python=python2.7 因为我的系统同时装了Python3,所以这里需要使用--python=python2.7指明需要使用哪个版本的python。执行后在~/my_python/下会出现 my_env 目录。

step3:安装MySQL-server或者MariaDB-Server,设置使用utf8字符集,skip-name-resolve=yes跳过名称解析,建立用户‘root’@‘127.0.0.1’,密码root,监听在127.0.0.1的3306端口上。create database mykey; 创建数据库。

setp4:cd ~/my_python 后执行 . ./my_env/bin/activate 启动脚本进入虚拟环境,后续工作都是在该虚拟环境中做的。pip安装的模块也是放置在虚拟环境中,这样的话若是普通用户通过pip安装模块,就不需要使用sudo了。

               pip install Django==1.8  安装Django    

               pip install pillow  安装pillow模块,用于生成验证码图片

               pip install MySQL-python 安装MySQL驱动模块 

step5:下面建立项目和应用, cd ~/my_python/,执行django.py startproject mykey  然后看到~/my_python/下出现新目录mykey,cd mykey 进入后执行 django.py startapp tools 建立名为tools的应用(一个目录),这时候在 ~/my_python/mykey 下有2个目录(mykey,tools)和1个脚本文件manage.py

====================== 下面开始写程序 ========================

<--mykey下settings.py -->

添加刚刚建立的应用tools,同时把默认使用的数据库从sqlite修改为MySQL,修改后如下:

Django小型项目练习:模拟商场储物柜  Django小型项目练习:模拟商场储物柜

<-- mykey下urls.py -->

urlpatterns = [
   url(r'^$', 'tools.views.index', name='home'),  //主页
   url(r'^chk/', 'tools.views.itemchk', name='home'),  //点击“查询”按钮则提交表单至该url
   url(r'^add/', 'tools.views.itemadd', name='home'),  //点击“添加”按钮则提交表单至该url
   url(r'^create_code_img/','tools.views.create_code_img',name='home'),  //点击验证码图片时提交到该url
]

<-- tools下新建forms.py -->  表单生成
#coding:utf-8  
from django import forms
class ChkForm(forms.Form):
   a=forms.CharField(label="请输入您要查询的key")
class AddForm(forms.Form):
   a=forms.CharField(label="请输入您要添加的info")

<-- tools下models.py -->  在数据库mykey建立表,名字为 tools_mysecret
from django.db import models
# Create your models here.
class MySecret(models.Model):
   key=models.CharField(max_length=16)
   info=models.CharField(max_length=256)
   flag=models.BooleanField(default='True')
   def __unicode__(self):
       return self.info

<-- tools下新建rankey.py -->  用于生成16个字符的随机数
import string
import random
KEY_LEN=16
def base_str():
   return (string.letters+string.digits)
def *******():
   keylist=[random.choice(base_str()) for i in range(KEY_LEN)]
   return("".join(keylist))


<-- tools下新建check_code.py --> 用于生成验证码图片

#coding:utf-8
import random
from PIL import Image,ImageDraw,ImageFont,ImageFilter
_letter_cases="abcdefghjkmnpqrstuvwxy"
_upper_cases=_letter_cases.upper()
_numbers=''.join(map(str,range(3,10)))
init_chars=''.join((_letter_cases,_upper_cases,_numbers))

def create_validate_code(size=(120,30),
chars=init_chars,
img_type="png",
mode="RGB",
bg_color=(255,255,255),
fg_color=(255,0,255),
font_size=18,
font_type="Hack-Bold.ttf",
length=4,
draw_lines=True,
n_line=(1,2),
draw_points=True,
point_chance=2):
   width,height=size
   img=Image.new(mode,size,bg_color)
   draw=ImageDraw.Draw(img)

   def get_chars():
       return random.sample(chars,length)
   def create_lines():
       line_num=random.randint(*n_line)
       for i in range(line_num):
           begin=(random.randint(0,size[0]),random.randint(0,size[1]))
       end=(random.randint(0,size[0]),random.randint(0,size[1]))
           draw.line([begin,end],fill=(0,0,0))
   def create_points():
       chance=min(100,max(0,int(point_chance)))
       for w in range(width):
           for h in range(height):
               tmp=random.randint(0,100)
               if tmp>100-chance:
                   draw.point((w,h),fill=(0,0,0))
   def create_strs():
       c_chars=get_chars()
       strs=' %s ' % ' '.join(c_chars)
       font=ImageFont.truetype(font_type,font_size)
       font_width,font_height=font.getsize(strs)
       draw.text(((width-font_width)/3,(height-font_height)/3),strs,font=font,fill=fg_color)
       return ''.join(c_chars)

   if draw_lines:
       create_lines()
   if draw_points:
       create_points()
   strs=create_strs()

   params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500
    ]
   img=img.transform(size,Image.PERSPECTIVE,params)
   img=img.filter(ImageFilter.EDGE_ENHANCE_MORE)
   return img,strs

<-- tools下views.py --> 
#coding:utf-8
from io import BytesIO
from django.shortcuts import render
from django.http import HttpResponse
from django.db.models.query import *

from .forms import ChkForm,AddForm
from .models import MySecret
from .rankey import *******
from .check_code import *

def index(request):
   chk_form=ChkForm()
   add_form=AddForm()
   return render(request,'index.html',{'form1':chk_form,'form2':add_form})
def itemchk(request):
   if request.method == 'POST':
       chk_form=ChkForm(request.POST)
       if chk_form.is_valid():
           a=chk_form.cleaned_data['a']
           post_check_code=request.POST.get('check_code')
           session_check_code=request.session['check_code']
           if post_check_code.lower()==session_check_code.lower():
               try:     
                   secitem=MySecret.objects.get(key=a)
                   if secitem.flag==1:
                       MySecret.objects.filter(key=a).update(flag=0)  
                       return HttpResponse(unicode(secitem.info))
                   else:    
                       return HttpResponse(str('该key已取出'))  
               except MySecret.DoesNotExist:
                   return HttpResponse(str('该key不存在'))  
           else:   
       return HttpResponse(str('验证码错误'))
       else:
           return HttpResponse(str('key不能为空'))

def itemadd(request):
   if request.method == 'POST':
       add_form=AddForm(request.POST)
       if add_form.is_valid():
           a=add_form.cleaned_data['a']
           mykey=*******()
          # b=add_form.cleaned_data['b']
          # MySecret.objects.create(key=a,info=b)
           MySecret.objects.create(key=mykey,info=a)
           return HttpResponse(str('请牢记您的key:'+mykey))
def create_code_img(request):
   f=BytesIO()
   img,code=create_validate_code()
   request.session['check_code']=code
   img.save(f,'png')
   return HttpResponse(f.getvalue(),content_type="image/png")

==========

cd ~/my_python/mykey/tools,建立templates目录 mkdir templates

cd templates 建立index.html 内容如下:

<-- index.html -->

<form action='/chk/' method='post'>

{% csrf_token %}
{{ form1 }}

<div class="row">
   <div class="col-xs-7">
       <input type="text" class="form-control" name="check_code" id="check_code" placeholder="请输入验证码">
   </div>   
   <div class="col-xs-5">
       <img id="check_code_img" src="/create_code_img/" onclick="javascript:window.location.reload();"/>
   </div>   
</div>

<input type="submit" value="查询">
</form>

<form action='/add/' method='post'>
{% csrf_token %}
{{ form2 }}
<input type="submit" value="添加">
</form>

结下来连接数据库建立表

cd ~/my_python/mykey/

./manage.py makemigrations

./manage.py migrate

./manage.py runserver  运行webserver,通过浏览器访问 127.0.0.1:8000 


相关文章:

  • 2021-11-21
  • 2022-12-23
  • 2021-05-12
  • 2021-12-25
  • 2021-08-16
  • 2022-12-23
  • 2021-11-27
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-04-14
  • 2021-11-23
  • 2021-08-28
  • 2021-08-30
  • 2022-01-11
  • 2022-12-23
相关资源
相似解决方案