上一篇讲了一下python 中Django 框架模块的一些基本概念,比如安装Django 模块,以及url的一些映射规则,以及Django 的模板语法!
这一篇就主要讲解Django 与后台数据库的一些联系。
首先新建好一个项目app中,若还不知道怎么用Django 命令新建项目和模块的可以先去看下我上一篇文章!讲解python Django 框架的基础使用
其次在models.py 中新建一个类比如:
#活动表
class Activity(models.Model):
cname = models.CharField(max_length=200)
ctime = models.CharField(max_length=50)
address = models.CharField(max_length=200)
price = models.CharField(max_length=100)
photo = models.CharField(max_length=200)
urlLink = models.CharField(max_length=150)
#用户表
class User(models.Model):
username = models.CharField(max_length=50)
password = models.CharField(max_length=50)
email = models.CharField(max_length=100)
phone = models.CharField(max_length=50)
新建好模型后,需要输入一行命令:python manage.py migrate # 创建表结构
,输入之后就会看到一个migrations的文件夹,在这个文件夹中会存储一些你对数据库的一些记录历史,然后如果你之后对models.py 文件做过任何改动之后,只需要再输入一条命令:python manage.py makemigrations app
用来更新数据库中的字段模型等
接下来就需要django 连接后台数据库了:
在settings.py 中将之前默认连接的sqlite3数据库注释掉,换成连接MySQL数据库,代码如下:
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bendibao',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
然后连接好之后,就需要去测试是否已经连接好了数据库,然后取出里面的数据了,于是我新建了一个testdb.py 文件:然后定义了一个方法,用来将后台数据库中的Activity表中的所有数据全部取出来:
def testdb(request):
list = Activity.objects.all()
# list2 = {}
list3 = []
i = 1
for var in list:
data = {}
data['id'] = i
data['cname'] = var.cname
data['ctime'] = var.ctime
data['address'] = var.address
data['price'] = var.price
data['photo'] = var.photo
data['urlLink'] = var.urlLink
#
# list2['id'] = i
# list2['data'] = data
list3.append(data)
i += 1
# a = json.dumps(data)
# b = json.dumps(list2)
# 将集合或字典转换成json 对象
c = json.dumps(list3)
return HttpResponse(c)
然后将该方法映射到一个url地址上:我们在urls.py 里面添加代码:
from django.conf.urls import url
from django.contrib import admin
from app import testdb
from app import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index),
url(r'^testdb$', testdb.testdb),
]
这样的话,启动之后,输入相对应的网址就可以取后台数据了,截图如下:
将后台中的所有数据都获取下来并且转换成json格式的形式,至于json样式的排版的这么好,是因为我在谷歌浏览器上装了一个jsonview 的插件,专门用来排版json格式的数据。
然后取到数据之后,就可以封装提供成一个接口提供给客户端使用了,大家应该知道从Android客户端请求,大部分主要是采用get请求或post请求方式两种,我这里就分别处理用get请求以及post请求然后返回的数据。
首先处理Get请求:
if(request.method == 'GET'):
print("parseData : " + "get data !")
#用get方式请求数据
username = request.GET.get('username' , "")
password = request.GET.get('password' , "")
email = request.GET.get('email' , "")
phone = request.GET.get('phone' , "")
user = User()
user.username = username
user.password = password
user.email = email
user.phone = phone
#保存一条用户数据
user.save()
print("cx getData" , "username : " + username +":password : " + password + ":email : " + email + ":phone:" + phone)
# 作为json 数组返回给客户端
data = {}
data['username'] = username
data['password'] = password
data['email'] = email
data['phone'] = phone
list = {}
list['data'] = data
list['state'] = 1
list['msg'] = "Get 正常"
response = json.dumps(list)
return HttpResponse(response)
这里主要是将客户端请求中的url中的参数截取下来,然后分别取出相对应的值,然后封装到一条数据存入本地数据库中,再将这条数据,封装成一个由data,state,msg组成的对象数组,返回给客户端,先看后台数据:
看下在Android客户端请求的代码:
//初始化键值对params
public List initNameAndParams(){
List list = new ArrayList<>();
list.add(new NameAndValue("username" , "cx3"));
list.add(new NameAndValue("password" , "4343543"));
list.add(new NameAndValue("email" , "[email protected]"));
list.add(new NameAndValue("phone" , "13710651984"));
return list;
}
//异步调用Get请求
public void getData(){
new Thread(new Runnable() {
@Override
public void run() {
HttpHelper.getInstance().getData(Constancts.TEST_URL , initNameAndParams());
}
}).start();
}
//用OkHttpClient 发起一个 get请求
public void getData(String url , List params){
if(params != null && params.size() > 0){
// params = encodeParamsJson(params);
StringBuilder mStringBuilder = new StringBuilder();
for(NameAndValue mNameValuePair : params){
mStringBuilder.append("&" + mNameValuePair.getName() + "=" + mNameValuePair.getValue());
}
Log.e("cx getData : params : " , mStringBuilder.toString() + ": url : " + url);
url = url + "?" + mStringBuilder.toString();
Log.e("cx getData : params : " , ": url : " + url);
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("cx: getData" + TAG , response.body().string());
}
});
}
这里是明文,没有用到AES加密的,所以可以看到这么清晰的数据,下一篇会讲到AES加密的相关知识,读者可以尽情期待哦。
讲完了Http 的Get请求方式,现在再来看看Post请求方式,同样还是先看看Python 的服务端的代码:
if(request.method == 'POST'):
print("parseData : " + "post data !")
# postBody = request.body
username = request.POST.get('username', "")
password = request.POST.get('password', "")
email = request.POST.get('email', "")
phone = request.POST.get('phone', "")
user = User()
user.username = username
user.password = password
user.email = email
user.phone = phone
#添加保存到数据库
user.save()
print("cx postData" , "username : " + user.username +":password : " + user.password + ":email : " + user.email + ":phone:" + user.phone)
#作为json 数组返回给客户端
data = {}
data['username'] = user.username
data['password'] = user.password
data['email'] = user.email
data['phone'] = user.phone
list = {}
list['data'] = data
list['state'] = 1
list['msg'] = "Post 正常"
response = json.dumps(list)
return HttpResponse(response)
AES加解密逻辑的代码我已经注释删除了,会在下一篇专门讲解。现在看下Android 客户端post方式请求的代码:
//用OkHttpClient 的post请求
public List initNameAndParams(){
List list = new ArrayList<>();
list.add(new NameAndValue("username" , "cx3"));
list.add(new NameAndValue("password" , "4343543"));
list.add(new NameAndValue("email" , "[email protected]"));
list.add(new NameAndValue("phone" , "13710651984"));
return list;
}
public void postData(String url , List params){
OkHttpClient client = new OkHttpClient();
//进行加密传输params 的value
// params = encodeParamsJson(params);
FormBody.Builder formBody = new FormBody.Builder();
for(NameAndValue nameAndValue : params){
formBody.add(nameAndValue.getName() , nameAndValue.getValue());
}
final Request request = new Request.Builder()
.url(url)
.post(formBody.build())
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
Log.e("cx : postData: " , result);
// JSONObject jsonObject = null;
// try {
// jsonObject = new JSONObject(result);
// String res = jsonObject.getString("data");
// Log.e("cx" , "a :" + res);
// String deCodes = AESUtils.deCode(res ,AESUtils.KEY);
//// String deCodes = AESUtils.deCode(a, AESUtils.KEY);
// Log.e("cx" , "deCodes : " + deCodes);
//
// String a = "npzI+QLvPDSbmIP6xaaZuj4ELpBBHD0w+lK4eoEjosyYt5gvfmRAyxIX/1F1Yx1hWmUZWFP2Buan\n" +
// "IrY1h4RmhhBaaV/WPPVbC5fBxQEkwTU=";
// Log.e("cx" , "a 1:" + a);
// System.out.println("加密result 22:" + a);
// String deResult1 = AESUtils.deCode(a , AESUtils.KEY);
// Log.e("cx" ,"deResult1:" + deResult1);
// } catch (JSONException e) {
// e.printStackTrace();
// }
// Gson gson = new Gson();
// Type apiType = new TypeToken>(){}.getType();
// List mApiResult = gson.fromJson(result, apiType);
}
});
然后就可以从客户端中取到post请求所响应的数据了!
上面的测试主要是另外一个user表 ,用来测试get请求,post请求的;然后,我用之前的testdb的url "http://127.0.0.1:8010/testdb"去请求得到的json数据给Android 客户端,然后在客户端中用RecyclerView展现出来:
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == GET_DATA_WHAT){
List list = (List) msg.obj;
data.clear();
data.addAll(list);
adapterBenDiPlay.setData(data);
rvPlay.setLayoutManager(new LinearLayoutManager(ActivityBendiPlay.this));
rvPlay.setAdapter(adapterBenDiPlay);
}
}
};
private void initData() {
data = new ArrayList<>();
adapterBenDiPlay = new AdapterBenDiPlay(ActivityBendiPlay.this , data);
new Thread(new Runnable() {
@Override
public void run() {
HttpGetHelper.get(Api.bendiHost, new HttpCallbackListener() {
@Override
public void onSuccess(String result) {
if(TextUtils.isEmpty(result)){
return;
}
Gson gson = new Gson();
Type apiType = new TypeToken>(){}.getType();
List mApiResult = gson.fromJson(result, apiType);
Message message = new Message();
message.what = GET_DATA_WHAT;
message.obj = mApiResult;
mHandler.sendMessage(message);
}
@Override
public void onError(Exception e) {
}
});
}
}).start();
}
这里用的是HttpClient做的请求,虽然被谷歌放弃了,但还是可以请求的,只需要在app的build.gradle中加入
useLibrary 'org.apache.http.legacy' 就可以使用了
/**
* get请求,获取返回字符串内容
*/
public static void get(String url, HttpCallbackListener httpCallbackListener) {
HttpGet httpGet = new HttpGet(url);
execute(url, httpGet, httpCallbackListener);
}
然后在手机端展现如图所示:由于服务端是在本地搭建的,并没有上传给自己的服务器中,所以在手机上需要连接本机电脑的代理IP地址,才能请求数据成功,并且返回正确的结果!!!
ok,写到这里,这篇博客就结束了,总结一下,主要讲了python django 框架连接后台数据库之后,再从数据库中取出数据后,然后处理客户端的get请求,post请求,封装成json数据然后提供接口,返回给Android客户端!!!