今天朋友接了一个小项目——做一个公司的官网,要求他一个人完成。找我帮忙让我帮写几个接口。于是想到前几天打算学习python来着,那么,就尝试用python来完成这个任务吧。
以下是从完全不懂python(但是我已经做了三年的java了)的情况下,从零开始做一个项目的过程笔记。
因为对于现在的我来说,python还是一个黑箱,所以这个笔记会比较乱,这个项目完成后会重新整理。
需求分析
需求很明确,就是一个公司的官网,除了大部分固定的内容之外,就是一个新闻系统了。
对于用户端来说,只要提供一个新闻列表、一个新闻详情的接口即可。
对于管理端来说,只需要新闻的增删改查几个接口即可。
技术选型
了解主流的python框架
在做java项目的时候,我们有很多可选的框架技术,比如springmvc、springboot等。那么python应该也会有相应的主流框架吧。
那么第一个关键字就是:
pyhon主流框架
输入金百度,“搜索工具”中选择最近一年。看了5个搜索结果,排除掉“转载”的内容相同的,得到的结果就是“Django”
Django
猜想,应该类似于springMvc,我需要的是restful的接口,那就看看Django能不能满足我的要求了。
接下来查的关键字是
Django restful
Django实现restful
看了几篇之,都是将具体的实现,终于找到一篇讲思路的
另外,作者还细心的写了“环境”,在环境里,我发现了一个不太熟悉的词“PyCharm”,那就查一下吧。
PyCharm是一个python的ide。
那太好了,有了这个ide应该就不用手动敲命令行了,效率提高了。
PyCharm
安装好P有charm,先创建一个新项目试试看。
发现里面直接由Django的选项,真实贴心,不管了,先所有的按照默认选项试试吧。
image
看到这个熟悉的界面,跟IntelliJ的一毛一样。玩了那么久的IntelliJ做java,那这个软件起步易如反掌。
按照IntelliJ的使用方式,试试看能不能把Django项目跑起来。
真的跑起来了。
image
image
Hello world
那么接下来肯定就是helloworld啦。
image
项目搭建
到目前为止我在没有看过python的语法的前提下已经把Django跑起来了。
那么接下来就要思考几个问题:
restfull
如何连数据库,连接池问题
后台的管理的权限怎么办
因为功能简单,加上这只是一个试水项目,所以项目构架分层什么的就不考虑了,如果按照spring的概念来说,就是直接在Controller里面读写数据库。
restfull
image
错误
1. 我先建一个package名为Api然后在里面建一个文件urls.py。
建立项目下属APP
$ django-admin startapp Api
根据教程安装
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$ pip install djangorestframework
Collecting djangorestframework
Downloading https://files.pythonhosted.org/packages/99/0b/d37a5a96c5d301e23adcabcc2f3fa659fb34e6308590f95ebb50cdbe98a1/djangorestframework-3.9.0-py2.py3-none-any.whl (924kB)
100% |████████████████████████████████| 931kB 233kB/s
Installing collected packages: djangorestframework
Successfully installed djangorestframework-3.9.0
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$ pip install markdown
Collecting markdown
Downloading https://files.pythonhosted.org/packages/7a/6b/5600647404ba15545ec37d2f7f58844d690baf2f81f3a60b862e48f29287/Markdown-3.0.1-py2.py3-none-any.whl (89kB)
100% |████████████████████████████████| 92kB 165kB/s
Installing collected packages: markdown
Successfully installed markdown-3.0.1
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$ pip install django-filter
Collecting django-filter
Downloading https://files.pythonhosted.org/packages/6a/8b/8517167a0adc45ce94d0873efb9487dd4cdeff7e10f96e837ad3d58f5837/django_filter-2.0.0-py3-none-any.whl (69kB)
100% |████████████████████████████████| 71kB 103kB/s
Requirement already satisfied: Django>=1.11 in ./venv/lib/python3.7/site-packages (from django-filter) (2.1.3)
Requirement already satisfied: pytz in ./venv/lib/python3.7/site-packages (from Django>=1.11->django-filter) (2018.7)
Installing collected packages: django-filter
Successfully installed django-filter-2.0.0
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$
根据教程配置
教程里只说“配置”,没有说写在哪个文件里,但是在前面的教程http://www.runoob.com/django/django-first-app.html里已经说了下面的文件是Django 项目的设置/配置,而且这里也刚好看到了 INSTALLED_APPS ,应该是这没错了。
image
打开AutoApi/Api/views.py 编写如下代码
from django.http import JsonResponse, HttpResponseNotAllowed, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from rest_framework import status
@csrf_exempt
def run_job(request):
# 判断请求头是否为json
if request.content_type != 'application/json':
# 如果不是的话,返回405
return HttpResponse('only support json data', status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
# 判断是否为post 请求
if request.method == 'POST':
try:
# 解析请求的json格式入参
data = JSONParser().parse(request)
except Exception as why:
print(why.args)
else:
content = {'msg': 'SUCCESS'}
print(data)
# 返回自定义请求内容content,200状态码
return JsonResponse(data=content, status=status.HTTP_200_OK)
# 如果不是post 请求返回不支持的请求方法
return HttpResponseNotAllowed(permitted_methods=['POST'])
打开bhjd_newmanager/Api/urls.py 编写如下代码
from django.conf.urls import url
from Api import views
urlpatterns = [
url(r'^runJob/$',views.run_job),
]
打开bhjd_newmanager/bhjd_newmanager/urls.py 修改如下代码
ALLOWED_HOSTS = '*' # 修改为* 代码允许任意host
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^', include('Api.urls')), # 新增
]
启动服务验证结果
image
至此restfull的问题解决了。
如何连数据库,处理连接池问题
那么接下来要查询的关键字就是“Django mysql”和“Django数据库连接池”。
Django使用mysql
百度查处了这样一篇文章:
那么开始实操吧。
安装mysqlclient
$ pip install mysqlclient
报错了
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$ pip install mysqlclient
Collecting mysqlclient
Downloading https://files.pythonhosted.org/packages/ec/fd/83329b9d3e14f7344d1cb31f128e6dbba70c5975c9e57896815dbb1988ad/mysqlclient-1.3.13.tar.gz (90kB)
100% |████████████████████████████████| 92kB 200kB/s
Complete output from command python setup.py egg_info:
/bin/sh: mysql_config: command not found
Traceback (most recent call last):
File "", line 1, in
File "/private/var/folders/50/kvjmxf5d2hg0rq39dlmsw7m80000gn/T/pip-install-g7bdz3of/mysqlclient/setup.py", line 18, in
metadata, options = get_config()
File "/private/var/folders/50/kvjmxf5d2hg0rq39dlmsw7m80000gn/T/pip-install-g7bdz3of/mysqlclient/setup_posix.py", line 53, in get_config
libs = mysql_config("libs_r")
File "/private/var/folders/50/kvjmxf5d2hg0rq39dlmsw7m80000gn/T/pip-install-g7bdz3of/mysqlclient/setup_posix.py", line 28, in mysql_config
raise EnvironmentError("%s not found" % (mysql_config.path,))
OSError: mysql_config not found
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/50/kvjmxf5d2hg0rq39dlmsw7m80000gn/T/pip-install-g7bdz3of/mysqlclient/
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(venv) zhaohandeMacBook-Pro:bhjd_newmanager zhaohan$
注意到这句话:
ou are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
忍不住手痒痒,升级了一把。
想看看新版的pip是否可以帮我解决这个问题,重新执行了一遍命令,还是报同样的错误。继续排查错误吧。
就把 /bin/sh: mysql_config: command not found 拿去搜一下。
他前面说要安装mysql-connector-c,不记得我是否安装过,就无脑再装一遍好了,如果已经安装了,应该会提示我。
再执行 pip install mysqlclient,错误变了
image
按照文章中的方式看看mysql_config
$ cd /usr/local/Cellar/mysql-connector-c/6.1.11/bin
# 修改前先备份
$ cp mysql_config mysql_config.backup
# 使用vi修改配置文件
$ sudo vim mysql_config
# 114 gg跳转到 114行
将
> # Create options
> libs="-L$pkglibdir"
> libs="$libs -l "
替换为
> # Create options
> libs="-L$pkglibdir"
> libs="$libs -lmysqlclient -lssl -lcrypto"
然后保存即可。
# 然后重新运行mysqlclient安装命令,之后一切顺利,大功告成
pip install mysqlclient
mysqlclient问题解决!
文章后面还提到另外一个问题,是连接mysql思维时候可能会出现的,等后面使用的时候遇到再说。
测试Django使用mysql
配置数据库连接
image
新建文件bhjd_newmanager/Api/models.py
创建一些模型去加到数据库里
from django.db import models
# Create your models here.
class Category(models.Model):
cate_name=models.CharField(max_length=200)
class news(models.Model):
n_title = models.CharField(max_length=200)
n_content = models.CharField(max_length=200)
n_is_publish = models.CharField(max_length=2)
n_category = models.CharField(max_length=2)
calss 定义的类名将会是数据库对应的表名,属性对应字段,不过表明有所偏差,假如你的应用名是blog ,class名是Book, 创建的表则是blog_book 数据库不区分大小写
在配置文件settings.py 修改
INSTALLED_APPS = [
...
'Api',
]
执行到这一步的时候,我已经不知道接下来该怎么办了,因为不理解稳重的Api.apps.BlogConfig的意思,再去找找其他的资料看有没有其他的发现,
在这篇文章https://www.cnblogs.com/stuqx/p/7127980.html里面发现,前面的Api应该是一个下属APP,而不是package这么简单,按照这篇文章的方法,创建一个下属APP,那么这里填这个下属APP的名字就行了
将models.py中的数据库表结构同步到MYSQL中
$ python manage.py migrate #创建表结构
$ python manage.py makemigrations Api #告诉django,Api中的表结构有更新
$ python manage.py migrate Api #执行Api中的表结构到mysql中
执行完之后发现表已经同步到了数据库中
image
这里担心一个问题:如果表中已经有数据了,我在项目中修改了表的结构,已经有的数据会不会丢失?
后面的测试就把代码放到view.py中去测试,比如:
image
数据表操作
增
test1 = news(n_title='标题', n_content='内容', n_category='测试', n_is_publish='1')
test1.save()
删
test1 = news.objects.get(id=1)
test1.delete()
news.objects.filter(n_title='testname').delete()
news.objects.all().delete()
改
test1 = news.objects.get(id=1)
test1.n_title = 'book1'
test1.n_content = 'xxxxxxx'
test1.save
news.objects.filter(n_title='testname').update(n_content = 'xxxxxxx')
news.objects.all().update(n_is_publish='1')
查
list = news.objects.all()
for i in list:
print(i.n_title)
list = news.objects.filter(n_title='testname', n_is_publish='1') #类似于SQL中的WHERE
list = news.objects.filter( n_title__contains='testuser') #注意中间是双下划线,类似于SQL中的where fromuser like "%testuser%"
#此外还有icontains(大小写无关的like),startswith和endswith, 还有range(SQL BETWEEN查询)
list = news.objects.get(n_title='testbookname') #返回单条记录,不需要for直接list.bookname使用
list = news.objects.filter().exclude().filter() #可无限嵌套
news.object.all()[:5] #前5条记录
news.object.order_by(n_title)[2:5] #排序后的第3、4、5条记录
news.object.order_by(n_title)[0] #排序后的第1条记录
news.object.order_by(n_title)[0:1].get() #排序后的第1条记录
news.object.all()[:10:2] #从第1条记录到第11条记录步长为2的数据集
__exact 精确等于 like ‘aaa’
__iexact 精确等于 忽略大小写 ilike ‘aaa’
__contains 包含 like ‘%aaa%’
__icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以…开头
__istartswith 以…开头 忽略大小写
__endswith 以…结尾
__iendswith 以…结尾,忽略大小写
__range 在…范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别
分页问题
查询关键字 “Django 分页”
Django内置了分页功能。
from django.core.paginator import Paginator
...
list = news.objects.all()
# 分页器,前面是总共的元素,limit是每页的元素个数
paginator = Paginator(list, limit)
print('页码数量', paginator.num_pages)
# 从页面获取页数信息,这里是获取?后参数page的value,
# 可以看到get后的‘page’并不是我们定义的,而是我们获取的
# 它的值就是个int
page = request.GET.get('page', 1)
# 显示某‘page’页面的信息
loaded = paginator.page(page)
# print('这里是loaded', loaded)
print('page_range', paginator.page_range)
pageobject_list = loaded.object_list
for i in pageobject_list:
print(i.n_title)
...
Django数据库连接池
Python就没有数据库连接池 😝😝😝😝😝😝
后台的管理的权限怎么办
Django admin
什么?后台管理?你可能还没听说过Django自带了一套后台管理吧?
如果你的需求不是很复杂,那就别太多事了。
session
首先想到的就是session,以下是session的使用方法。
但是如果网站是前后端分离的,session就不好使了,就要考虑token了。
#1、生成随机字符串(sessionID)
#2、通过cookie发送给客户端
#3、服务端保存{zhanggen随机字符串:{'name':'zhanggen'.'email':'zhanggen@le.com'}}
request.session['name']=obj.username #在Django 中一句话搞定
request.session['email'] = 'zhanggen@le.com'
#1、获取客户端的 sessionID
#2、在服务端查找是否存在 这个sessionID
#3、在服务端查看对应的key sessionID键的值中是否有name(有值就是登录过了!!)
v=request.session.get('name')
print(v)
if v:
return render(request,'index.html',{'msg':v})
else:return redirect('/login/')
token
在spring开发接口的时候,使用jwt做token,那么看看有没有python版本的。
关键字“Django jwt”
这里就不说怎么安装和配置了。因为我要做的系统很简单,Django admin就能满足。
结尾
这个小项目,从完全不懂python到此,用了三个小时。
�
我们很多人在做一件事情之前,总会犹豫自己是否掌握了做这件事的每个要素,如果没有就先去学习基础。
其实做事除了基本的技能之外,最重要的思考能力和分析能力。平日历重复的工作中我们能得到什么,如果你想不到钱之外的其他的话,那么思考能力和分析能力将会是一个很好的选择。