当前位置:   article > 正文

Python项目(超详细)

python项目

#前言:

该项目的目的是做一个类似管理数据的系统,主要训练的是将数据库、前端、后端很好的对接起来,并且可以实现在前端页面就可以对数据进行一个增删改查,内容很详细,代码多有注释,建议先将我下面提及到的文件导入,再看代码会更加详细。如若有需要改正的地方,欢迎各位前来指正。后续会继续更新好文,欢迎大家前来关注!

一、项目前期配置准备:


1、配置数据库引擎:

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.mysql',
  4. 'NAME': 'booksystem',
  5. 'HOST':'127.0.0.1',
  6. 'USER':'root',
  7. 'PASSWORD':' '
  8. }
  9. }
'
运行

2、配置静态文件的检索路径,在项目的根目录中创建 static 文件:

同样是在setting.py文件中:

  1. STATIC_URL = '/static/'
  2. STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

创建文件:

3、导入 html 模板文件 和 静态文件数据:

导入静态文件数据:

静态文件数据在我的百度网盘中有:需要的可以直接去拿。

链接:https://pan.baidu.com/s/1teodItF9woC8EN5HuJ05zA 
提取码:abmd

(注意将文件拿到后直接拖拽到static里面即可)

里面的代码:关于背景图之类的可以自行更改。

导入html模板文件:

关于html文件,我也已经有写的初版,可以先行将其导入。

在我的百度网盘可以自行免费拿:

链接:https://pan.baidu.com/s/1Xx54Z5yrrSv5DdOCBX0JxA 
提取码:ammd

二、用户注册:

1、响应用户注册页面的视图:

  1. class RegisterView(View):
  2. '''
  3. 用户注册视图
  4. '''
  5. def get(self , request):
  6. # 响应注册页面
  7. return render(request , 'register.html')

2、定义用户数据模型类 , 保存用户注册的个人数据信息:

  1. class User(models.Model):
  2. '''
  3. 保存用户注册数据
  4. '''
  5. username = models.CharField(max_length=20)
  6. password = models.IntegerField()
  7. email = models.EmailField()

3、设置后端对用户注册数据进行验证,在对应的应用下创建一个 forms 的文件,实现数据验证:

注意,这里的forms文件中,主要是对在注册页面输入的数据进行验证是否符合规则,此时还没有与数据库进行对接。

而如何与视图文件响应,就是在类视图的将post请求得到的数据传输给forms组件中用来检测的类,然后调用。

注意,下述代码中:

首先,要对用户名,密码,再次输入密码进行验证长度是否正确。

其次,验证两次输入的密码是否一致。

最后验证邮箱的格式与用户名的格式。(用户名的格式采用的是正则表达式,而邮箱格式采用forms.EmailField,可以自行验证。)

  1. from django import forms
  2. import re
  3. class RegisterForm(forms.Form):
  4. '''
  5. 验证用户注册数据
  6. '''
  7. username = forms.CharField(max_length=15 , min_length=3,
  8. error_messages={
  9. "max_length":"用户名长度超出",
  10. "min_length":"用户名长度不足",
  11. "required":"用户名不允许为空",
  12. })
  13. password = forms.CharField(max_length=15 , min_length=6,
  14. error_messages={
  15. "max_length":"密码长度超出",
  16. "min_length":"密码长度不足",
  17. "required":"密码不允许为空",
  18. })
  19. resetpw = forms.CharField(max_length=15 , min_length=6,
  20. error_messages={
  21. "max_length":"密码长度超出",
  22. "min_length":"密码长度不足",
  23. "required":"密码不允许为空",
  24. })
  25. email = forms.EmailField(error_messages={'invalid':'邮箱格式不正确',
  26. 'required':'邮箱不允许为空'})
  27. def clean_username(self):
  28. name = self.cleaned_data.get("username")
  29. if not re.match(r'^[A-Za-z0-9_]{3,15}$' , name):
  30. self.add_error('username' , '用户名格式不正确')
  31. return name
  32. def clean(self):
  33. pwd1 = self.cleaned_data.get('password')
  34. pwd2 = self.cleaned_data.get('resetpw')
  35. if pwd1 != pwd2:
  36. self.add_error('resetpw' , '两次密码不一致')
  37. return self.cleaned_data

4、在注册视图中接收用户注册数据,进行数据验证:

这个验证主要是针对当用户输入注册的数据合理时候,是否已经符合注册规则,包括验证码的识别。

此时注册视图类变为:

  1. class RegisterView(View):
  2. '''
  3. 用户注册视图
  4. '''
  5. def get(self,request):
  6. return render(request,'register.html')
  7. #响应注册页面
  8. def post(self,request):
  9. #接收用户注册输入的数据
  10. #传递给forms组件中进行数据验证
  11. register_form=RegisterForm(request.POST)#先获取这个POST请求的所有数据,然后在下面再进行判断
  12. #判断forms组件是否返回异常
  13. if register_form.is_valid():
  14. #获取数据
  15. username=register_form.cleaned_data.get('username')
  16. password=register_form.cleaned_data.get('password')
  17. email=register_form.cleaned_data.get('email')
  18. else:
  19. return render(request,'register.html',locals())
  20. #用户不合法,数据返回前端页面

此时在负责响应上面内容的register.html页面中:

当用户数据异常不合法的情况下 ,后端将异常信息返回到前端。

  1. <div class="form-group">
  2. <i class="fa fa-user" aria-hidden="true"></i>
  3. 用户名:<input class="form-control required" type="text" name="username" id="username"
  4. placeholder="请输入用户名" required v-model="username" @blur="check_name">
  5. <span style="color: #a94442" v-show="error_username">[[ error_name_message ]]</span>
  6. </div>
  7. <div class="form-group">
  8. <i class="fa fa-key" aria-hidden="true"></i>
  9. 密码:<input class="form-control required" type="password" name="password" id="password" placeholder="请输入密码"
  10. required v-model="password" @blur="check_password">
  11. <span style="color: #a94442">{{ register_form.password.errors.0 }}</span>
  12. </div>
  13. <div class="form-group">
  14. <i class="fa fa-check-circle-o" aria-hidden="true"></i>
  15. 确认密码:<input class="form-control required" type="password" name="resetpw" id="resetpw" placeholder="请确认密码"
  16. required v-model="resetpw" @blur="check_resetpw">
  17. <span style="color: #a94442">{{ register_form.resetpw.errors.0 }}</span>
  18. </div>
  19. <div class="form-group">
  20. <i class="fa fa-envelope" aria-hidden="true"></i>
  21. 邮箱:<input class="form-control required" type="email" name="email" id="email" placeholder="请输入邮箱">
  22. <span style="color: #a94442">{{ register_form.email.errors.0 }}</span>
  23. </div>
  24. <div class="form-group">
  25. <i class="fa fa-envelope" aria-hidden="true"></i>
  26. 验证码:<input class="form-control required" type="text" name="image_code" id="image_code" placeholder="请输入验证码">
  27. <img v-bind:src="image_code_url" class="img_code" @click="image_code">
  28. <span style="color: red">{{ code_error }}</span>
  29. </div>

注意这里涉及到vue了所以在下面body标签下导入script标签导入静态文件中的js内容:

  1. <script src="/static/bootstrap-3.4.1-dist/js/vue-2.5.16.js"></script>
  2. <script src="/static/bootstrap-3.4.1-dist/js/axios-0.18.0.min.js"></script>
  3. <script src="/static/bootstrap-3.4.1-dist/js/register.js"></script>

5、实现图片验证码

注意:

关于验证码的实现我在这儿再次提及一下:详细在我上篇博客中有讲解。

1.在当前的应用下创建包 —— ImageCode:

上面各个文件的内容可以查看博客:Django之图片验证码的创建(超详细)-CSDN博客

2.实现验证码的视图:

  1. from PIL import Image,ImageDraw,ImageFont
  2. from random import randint,choice
  3. import os
  4. import io
  5. def get_random_code():
  6. # 随机数字
  7. number = str(randint(0,9))
  8. # 随机大写字母
  9. upper = chr(randint(65 , 90))
  10. # 随机小写字母
  11. lower = chr(randint(97 , 122))
  12. # 在生成的大小写字母和数字中随机获取一个
  13. code = choice([number , upper , lower])
  14. return code
  15. def get_color():
  16. return (randint(0,255),randint(0,255),randint(0,255))
  17. def create_image():
  18. # 创建图片对象
  19. image = Image.new(mode="RGB", size=(120, 30), color=get_color())
  20. # 创建画笔工具
  21. draw = ImageDraw.Draw(image)
  22. # 设置字体 , 导入字体文件,设置字体大小
  23. dir=os.path.join(os.path.dirname(__file__),'fonts','COOPBL.TTF')
  24. font = ImageFont.truetype(dir, 24)
  25. # 制作图片噪点
  26. # 噪点
  27. for i in range(100):
  28. # point([图片坐标] , fill颜色)
  29. draw.point([randint(0, 180), randint(0, 30)], fill=get_color())
  30. # 噪线
  31. for i in range(10):
  32. draw.line([randint(0, 180), randint(0, 30), randint(0, 180), randint(0, 30)], fill=get_color())
  33. # 弧线
  34. x = randint(0, 180)
  35. y = randint(0, 30)
  36. for i in range(10):
  37. draw.arc([x, y, x + 1, y + 1], 0, 90, fill=get_color())
  38. #定义一个变量用来拼接生成的验证码;
  39. text=''
  40. # 生成验证码
  41. for i in range(4):
  42. c = get_random_code()
  43. # 将获取到的验证码写入到图片中
  44. draw.text((10 + 30 * i, 2), text=c, fill=get_color(), font=font)
  45. text+=c#拼接后的验证码
  46. # 图片保存为文件,这里不需要保存 就把他保存到内存中
  47. out=io.BytesIO()
  48. image.save(out, format='png')
  49. return out.getvalue(),text
  50. create_image()

响应验证码:

  1. def CodeImage(request):
  2. # 响应图片验证码视图
  3. # 获取图片验证码
  4. image,text = create_image()
  5. # session 会话
  6. # 将验证码数据保存到 session 会话中, 这个会话是以键值对的方式保存
  7. request.session['code'] = text
  8. # 将图片验证码响应到页面
  9. return HttpResponse(image, content_type='image/png')
'
运行
path('image_code/',views.CodeImage)

6、前端的数据校验,使用 vue 的框架进行数据校验:

在标签中板顶数据信息 , 以及对文本框绑定对应的方法

  1. <div class="form-group">
  2. <i class="fa fa-user" aria-hidden="true"></i>
  3. 用户名:<input class="form-control required" type="text" name="username" id="username"
  4. placeholder="请输入用户名" required v-model="username" @blur="check_name">
  5. <span style="color: red">{{ register_form.username.errors.0 }}</span>
  6. </div>

在静态文件对应位置中创建 register.js 文件

在register.js文件中进行ajax请求以及数据验证:

  1. let vm = new Vue({
  2. el : '#app',
  3. delimiters: ['[[' , ']]'],
  4. data :{
  5. username:'',
  6. password:'',
  7. resetpw:'',
  8. image_code_url:'',
  9. error_username:false,
  10. error_password:false,
  11. error_resetpw:false,
  12. error_name_message:'',
  13. },
  14. // 这个方法会在 html 页面执行的时候 , 自动调用里面的内容
  15. mounted(){
  16. this.image_code();
  17. },
  18. // 定义检查方法
  19. methods:{
  20. // 生成图片验证码
  21. image_code(){
  22. // 短时间内路径一致的情况下,会无法响应成功
  23. // 添加时间参数,保证在短时间内请求路由不一致
  24. this.image_code_url = '/image_code/?'+ new Date().getTime()
  25. },
  26. // 验证用户名
  27. check_name(){
  28. // 定义用户名的规则范围
  29. let re = /^[A-Za-z0-9_]{3,15}$/;
  30. // 判断用户名是否满足定义的规则
  31. if(re.test(this.username)){
  32. // 用户名合法
  33. this.error_username = false
  34. } else {
  35. // 用户名不合法
  36. this.error_username = true;
  37. this.error_name_message = '用户名不合法';
  38. }
  39. // 判断用户名是否重复
  40. if(this.error_username == false){
  41. // 发送 ajax 请求
  42. axios.get(
  43. '/count/'+this.username+'/',
  44. {responseType:'json'}
  45. )
  46. // 请求成功
  47. .then(response =>{
  48. if (response.data.count > 0){
  49. // 用户已存在
  50. this.error_username = true;
  51. this.error_name_message = '用户名已存在';
  52. } else {
  53. this.error_username = false;
  54. }
  55. })
  56. // 请求失败
  57. .catch(error => {
  58. console.log(error.response)
  59. })
  60. }
  61. },
  62. // 校验密码
  63. check_password(){
  64. let re = /^[a-zA-Z0-9]{6,15}$/;
  65. if(re.test(this.password)){
  66. // 密码字符合法
  67. this.error_password = false
  68. } else {
  69. this.error_password = true
  70. }
  71. },
  72. // 校验两次密码输入是否一致
  73. check_resetpw(){
  74. if(this.password == this.resetpw){
  75. this.error_resetpw = false
  76. } else {
  77. this.error_resetpw = true
  78. }
  79. }
  80. }
  81. })

7.校验用户名是否重复:

  1. # 检查用户名重复
  2. re_path('count/(?P<username>[A-Za-z0-9_]{3,15})/' , views.username_count),
  3. def username_count(request , username):
  4. # 从数据库中获取用户数据
  5. count = User.objects.filter(username=username).count()
  6. return JsonResponse({'code':200 , 'errmsg':"OK" , 'count':count})

此时的路由文件中:

  1. path('admin/', admin.site.urls),
  2. path('register/',views.RegisterView.as_view()),#用户注册
  3. path('image_code/',views.CodeImage),#图片验证码
  4. re_path('count/(?P<username>[A-Za-z0-9_]{3,15})/',views.username_count),#检查用户名重复
  5. #这个路由是count/,而后面的内容是利用正则表达式将用户名传入校验过程,这个在register.js中将这个路由传递进去用了

此时的页面显示:

7、在注册视图中,实现图片验证码的校验:

  1. def post(self , request):
  2. # 接收用户注册输入的数据
  3. # 传递给 forms 组件中进行数据验证
  4. register_form = RegisterForm(request.POST)
  5. # 判断 forms 组件是否有返回异常信息
  6. if register_form.is_valid():
  7. # 数据没问题,获取数据
  8. username = register_form.cleaned_data.get('username')
  9. password = register_form.cleaned_data.get('password')
  10. email = register_form.cleaned_data.get('email')
  11. # 获取用户输入的验证码
  12. image_code = request.POST.get('image_code')
  13. # 校验验证码,从 session 会话中获取保存的验证码
  14. code = request.session['code']
  15. if image_code == code:
  16. # 验证码正确,将数据保存到数据库中,注册成功 ;否则注册失败
  17. User.objects.create(username=username , password=password , email=email)
  18. # 注册成功响应到登录页
  19. return redirect('/login/')
  20. else:
  21. # 验证码错误
  22. return render(request, 'register.html', {'code_error':'验证码错误'})
  23. else:
  24. # 用户数据不合法 , 将异常信息返回给前端页面
  25. return render(request , 'register.html' , locals())
'
运行

在验证了用户名密码验证码等之后,会将其传入一开始创建的数据库中。

三、用户登录:

1、用户登录视图:

  1. # 用户登录
  2. path('login/' , views.LoginView.as_view()),
  3. class LoginView(View):
  4. '''
  5. 用户登录
  6. '''
  7. def get(self , request):
  8. return render(request , 'login.html')

2、接收用户登录的数据:

  1. class LoginView(View):
  2. '''
  3. 用户登录
  4. '''
  5. def get(self , request):
  6. return render(request , 'login.html')
  7. def post(self , request):
  8. login_form = LoginForm(request.POST)
  9. if login_form.is_valid():
  10. username = login_form.cleaned_data.get('username')
  11. password = login_form.cleaned_data.get('password')
  12. # 到数据库进行查询用户数据是否存在
  13. user = User.objects.filter(username=username , password=password)
  14. if user:
  15. # 登录成功 , 重定向到 首页
  16. return redirect('/index/')
  17. else:
  18. return render(request, 'login.html', {'errormsg': '账号或者密码错误'})
  19. else:
  20. return render(request , 'login.html' , {'errormsg':'账号或者密码错误'})

3.检测用户登录数据:

同样在forms文件下:

  1. class LoginForm(forms.Form):
  2. #检测校验用户登录
  3. username = forms.CharField(max_length=15, min_length=3,
  4. error_messages={
  5. "max_length": "用户名长度过长",
  6. "min_length": "用户名长度不足",
  7. "required": "用户名不能为空",
  8. })
  9. password = forms.CharField(max_length=15, min_length=6,
  10. error_messages={
  11. "max_length": "密码名长度过长",
  12. "min_length": "密码名长度不足",
  13. "required": "密码不能为空",
  14. })
  15. def clean_username(self):
  16. name=self.cleaned_data.get("username")
  17. if not re.match(r'^[A-Za-z0-9_]{3,15}$',name):
  18. self.add_error('username','用户名格式不正确')
  19. return name

4.响应首页面:

  1. # 首页
  2. path('index/' , views.index),
  3. def index(request):
  4. # 响应首页
  5. return render(request , 'index.html')

此时的登录页:

四、机器人管理页面:

1、定义机器人模型类:

  1. class PublishingHouse(models.Model):
  2. '''
  3. 出版社的信息
  4. '''
  5. # 机器人的名称
  6. name = models.CharField(max_length=25)
  7. # 机器人类型
  8. publisher_type = models.CharField(max_length=15)
  9. # 机器人的工作时间
  10. create_time = models.DateField()
  11. # 机器人的工作的地址
  12. address = models.CharField(max_length=50)

2、设置机器人信息页面:

  1. {% block main%}
  2. <table border="1" class="table table-hover table-bordered">
  3. <thead>
  4. <tr>
  5. <td>序号</td>
  6. <td>机器人名称</td>
  7. <td>机器人类型</td>
  8. <td>机器人工作时间</td>
  9. <td>机器人地址</td>
  10. <td>操作</td>
  11. </tr>
  12. </thead>
  13. <thead>
  14. {% for pub in publisher %}
  15. <tr>
  16. <td>{{ pub.id }}</td>
  17. <td>{{ pub.name }}</td>
  18. <td>{{ pub.publisher_type }}</td>
  19. <td>{{ pub.create_time }}</td>
  20. <td>{{ pub.address }}</td>
  21. <td>
  22. <a href="#">修改</a>
  23. <a href="#">删除</a>
  24. </td>
  25. </tr>
  26. {% endfor %}
  27. </thead>
  28. </table>
  29. {% endblock %}

3、设置响应添加机器人数据后的类:

这个就是把数据库里面所有关于机器人的信息全部都响应出来,重新放到这个页面。

  1. # 出版社列表页
  2. path('publisher_list/' , views.publisher_list),
  3. def publisher_list(request):
  4. # 出版社列表
  5. publisher = PublishingHouse.objects.all()
  6. return render(request , 'publisher_list.html' , {'publisher':publisher})

4、添加机器人信息:

  1. {% block main %}
  2. <form method="post">
  3. {% csrf_token %}
  4. <P></P>
  5. <p>机器人名称:<input type="text" name="name"></p>
  6. <p>机器人类型:<input type="text" name="publisher_type"></p>
  7. <p>机器人工作时间:<input type="date" name="create_time"></p>
  8. <p>机器人地址:<input type="text" name="address"></p>
  9. <p><button type="submit" class="btn">提交</button></p>
  10. </form>
  11. {% endblock %}
  1. class AddPublishView(View):
  2. '''
  3. 添加机器人信息
  4. '''
  5. def get(self,request):
  6. return render(request,'add_publisher.html')
  7. def post(self,request):
  8. #拿数据
  9. name=request.POST.get('name')
  10. publisher_type=request.POST.get('publisher_type')
  11. create_time=request.POST.get('create_time')
  12. address=request.POST.get('address')
  13. #保存到数据库
  14. PublishingHouse.objects.create(
  15. name=name,
  16. publisher_type=publisher_type,
  17. create_time=create_time,
  18. address=address,
  19. )
  20. #数据保存成功,重定向到页表页面
  21. return redirect('/publisher_list/')

此时的页面为:

5、修改机器人信息:

修改信息的主要思路为,将要修改的内容的ID先行找出,然后对其进行更改后响应到数据库当中,然后再将数据库内容重新全部响应到页面当中。

实现修改数据的模板页面:

  1. {% block main %}
  2. <form method="post">
  3. {% csrf_token %}
  4. <p><span>机器人名称:</span><input type="text" name="name" value="{{ edit_data.name }}"></p>
  5. <p><span>机器人类型:</span><input type="text" name="publisher_type" value="{{ edit_data.publisher_type }}"></p>
  6. <p><span>机器人工作时间:</span><input type="date" name="create_time" value="{{ edit_data.create_time }}"></p>
  7. <p><span>机器人地址:</span><input type="text" name="address" value="{{ edit_data.address }}"></p>
  8. <p><button type="submit" class="btn">提交</button></p>
  9. </form>
  10. {% endblock %}
  1. class EditPublisherView(View):
  2. '''
  3. 修改出版社信息
  4. '''
  5. def get(self , request):
  6. # 获取用户要修改的机器人 id
  7. id = request.GET.get('id')
  8. edit_data = PublishingHouse.objects.get(id=id)
  9. return render(request , 'edit_publisher.html' , {'edit_data':edit_data})
  10. def post(self , request):
  11. id = request.GET.get('id')
  12. name = request.POST.get('name')
  13. publisher_type = request.POST.get('publisher_type')
  14. create_time = request.POST.get('create_time')
  15. address = request.POST.get('address')
  16. edit_data = PublishingHouse.objects.filter(id=id)
  17. edit_data.update(
  18. name=name,
  19. publisher_type=publisher_type,
  20. create_time=create_time,
  21. address=address
  22. )
  23. return redirect('/publisher_list/')

注意响应到这个页面用的是get请求,所以先用get请求将它数据响应出来(主要是为了找到所修改的id),用post请求将修改后的数据改到数据库当中。

修改页:

5、删除机器人信息:

  1. # 删除机器人信息
  2. path('del_publisher/' , views.del_publisher),
  3. def del_publisher(request):
  4. id = request.GET.get('id')
  5. PublishingHouse.objects.filter(id=id).delete()
  6. return redirect('/publisher_list/')

注意:这一步很重要,将修改和删除的路由链接上:

五、机器人信息页面:

1、机器人信息的模型类:

  1. class Book(models.Model):
  2. '''
  3. 机器人信息
  4. '''
  5. name = models.CharField(max_length=20)
  6. # 机器人名称
  7. carrier = models.CharField(max_length=10)
  8. # 功能
  9. publisher_time = models.DateField()
  10. # 图片:
  11. book_image = models.CharField(max_length=20)
  12. # 简介
  13. book_intro = models.CharField(max_length=500)
  14. # 价格
  15. price = models.DecimalField(max_digits=5 , decimal_places=2)
  16. inventory = models.IntegerField()
  17. publisher = models.ForeignKey(to='PublishingHouse' , on_delete=models.CASCADE)

2、响应机器人列表页:

  1. # 图书列表页
  2. path('book_list/' , views.book_list),
  3. def book_list(request):
  4. book = Book.objects.all()
  5. return render(request , 'book_list.html' , {'book':book})

前端页面:

  1. {% endblock %}
  2. {% block main %}
  3. <table border="1" class="table table-hover table-bordered">
  4. <thead>
  5. <tr>
  6. <td>序号</td>
  7. <td>机器人名称</td>
  8. <td>价格</td>
  9. <td>机器人工作性质</td>
  10. <td>库存</td>
  11. <td>查询详情</td>
  12. <td>操作</td>
  13. </tr>
  14. </thead>
  15. <thead>
  16. {% for b in book %}
  17. <tr>
  18. <td>{{ b.id }}</td>
  19. <td>{{ b.name }}</td>
  20. <td>{{ b.price }}</td>
  21. <td>{{ b.carrier }}</td>
  22. <td>{{ b.inventory }}</td>
  23. <td><a href="/check_book/?id={{ b.id }}">查看</a></td>
  24. <td>
  25. <a href="/edir_publisher/?id={{ b.id }}">修改</a>
  26. <a href="/del_publisher/?id={{ b.id }}">删除</a>
  27. </td>
  28. </tr>
  29. {% endfor %}
  30. </thead>
  31. </table>
  32. {% endblock %}

3.添加机器人信息:

  1. class AddBookView(View):
  2. '''
  3. 添加机器人信息
  4. '''
  5. def get(self , request):
  6. # 获取机器人信息
  7. publisher = PublishingHouse.objects.all()
  8. return render(request , 'add_book.html' , {"publisher":publisher})
  9. def post(self , request):
  10. name = request.POST.get('name')
  11. carrier = request.POST.get('carrier')
  12. number = request.POST.get('number')
  13. time = request.POST.get('time')
  14. book_image = request.FILES.get('book_image')
  15. book_intro = request.POST.get('book_intro')
  16. price = request.POST.get('price')
  17. inventory = request.POST.get('inventory')
  18. publisher_id = request.POST.get('publisher_id')
  19. # 在项目的静态文件夹中创建一个文件夹保存机器人的图片
  20. if book_image:
  21. # 获取文件名
  22. book_image_name = book_image.name
  23. # 获取到图片的保存位置
  24. image_dir = os.path.join(STATICFILES_DIRS[0] , 'book_image' , book_image_name)
  25. with open(image_dir , 'wb') as f:
  26. for i in book_image:
  27. f.write(i)
  28. else:
  29. book_image = '暂无.jpg'
  30. if not book_intro:
  31. book_intro = '暂无作品介绍, 正在整理中……'
  32. Book.objects.create(
  33. name=name,
  34. carrier=carrier,
  35. #number_of_words=number,
  36. publisher_time=time,
  37. book_image=book_image,
  38. book_intro=book_intro,
  39. price=price,
  40. inventory=inventory,
  41. publisher_id=publisher_id
  42. )
  43. return redirect('/book_list/')
  1. {% endblock %}
  2. {% block main %}
  3. <form method="post" enctype="multipart/form-data">
  4. {% csrf_token %}
  5. <p>机器人名称:<input type="text" name="name"></p>
  6. <p>功能:<input type="text" name="carrier"></p>
  7. <p>推出时间:<input type="date" name="time"></p>
  8. <p>图片:<input type="file" name="book_image"></p>
  9. <p>简介:<textarea rows="12" cols="25" name="book_intro"></textarea></p>
  10. <p>价格(/天):<input type="text" name="price"></p>
  11. <p>库存:<input type="text" name="inventory"></p>
  12. <p>类型:<select multiple name="publisher_id">
  13. {% for foo in publisher %}
  14. <option value="{{ foo.id }}">{{ foo.name }}</option>
  15. {% endfor %}
  16. </select>
  17. </p>
  18. <p><button type="submit" class="btn">提交</button></p>
  19. </form>
  20. {% endblock %}

此时的页面为:

六、总结:

该篇博客主要利用Django框架与Mysql实现一个项目操作,至于其它页面的实现,它的涉及思路都和上述页面实现一样,有兴趣可以自行扩充、优化。小编后续还会继续更新内容,欢迎各位大佬的指导,也欢迎各位关注我坐等后续,您的支持是我变强的最大动力!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/1003494
推荐阅读
相关标签
  

闽ICP备14008679号