2018-04-09 21:43:18 mm1030533738 阅读数 3917
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13376 人正在学习 去看看 郭宏志

序:以前一直想找到一个搭建app后台的框架,尝试过springboot,以及基于springboot的Guns(Guns官方的教程价格鄙视了我~)。直到回到最初的Django,之前很早使用过一点,还是觉得Django是真正的方便。


完成android登录后台
①创建项目以及app
②基本设置,登录注册逻辑及反馈
③开启服务进行测试

①创建项目以及app




②基本设置,登录注册逻辑及反馈








 public void sendRequest() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL(urlLoginOrSign);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                    String user_id = id.getText().toString();
                    String user_password = password.getText().toString();
                    out.writeBytes("username="+user_id+"&password="+user_password);
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) response.append(line);
                    Log.d(TAG, response.toString());
                    
                    //!!!这是一个极大的错误:在线程里处理不能更新UI,Toast也是不能的
                    //Toast.makeText(LoginActivity.this,response.toString(),Toast.LENGTH_SHORT).show();

                    //如果登录成功,并且已经点击了“记住密码”,则会保存该密码
                    SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
                    if (response.toString().equals("登录成功") ){
                        //关闭等待登录窗口
                        progressDialog.dismiss();
                        Message msg = new Message();
                        msg.what = 0;
                        handle.sendMessage(msg);
                        if (rememberPass.isChecked())
                        {
                            String ac = id.getText().toString();
                            String pa = password.getText().toString();
                            editor.putBoolean("Remember_password", true);
                            editor.putString("Account", ac);
                            editor.putString("Password", pa);
                        }
                        else
                        {
                            editor.clear();
                        }
                        editor.apply();
                    }else if(response.toString().equals("登录失败") ){
                        //关闭等待登录窗口
                        progressDialog.dismiss();
                        Message msg = new Message();
                        msg.what = 1;
                        handle.sendMessage(msg);
                        if (rememberPass.isChecked())
                        {
                            String ac = id.getText().toString();
                            String pa = password.getText().toString();
                            editor.putBoolean("Remember_password", true);
                            editor.putString("Account", ac);
                            editor.putString("Password", pa);
                        }
                        else
                        {
                            editor.clear();
                        }
                        editor.apply();
                    }else if(response.toString().equals("用户不存在") ){
                        //关闭等待登录窗口
                        progressDialog.dismiss();
                        Message msg = new Message();
                        msg.what = 2;
                        handle.sendMessage(msg);
                        if (rememberPass.isChecked())
                        {
                            String ac = id.getText().toString();
                            String pa = password.getText().toString();
                            editor.putBoolean("Remember_password", true);
                            editor.putString("Account", ac);
                            editor.putString("Password", pa);
                        }
                        else
                        {
                            editor.clear();
                        }
                        editor.apply();
                    }
                } catch (MalformedURLException e) {
                    Log.e(TAG, "url form wrong");
                } catch (IOException e) {
                    Log.e(TAG, "IOException 1:" + e.getMessage());
                } finally {
                    if (reader != null) {
                        try { reader.close(); }
                        catch (IOException e) { Log.e(TAG, "IOException 2:" +e.getMessage()); }
                    }
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
    private Handler handle = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    Toast.makeText(LoginActivity.this,"登录成功!",Toast.LENGTH_SHORT).show();
                    LoginActivity.this.finish();
                    break;
                case 1:
                   Toast.makeText(LoginActivity.this,"密码错误!",Toast.LENGTH_SHORT).show();
                   break;
                case 2:
                    Toast.makeText(LoginActivity.this,"用户不存在!",Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };


③开启服务进行测试


可以在浏览器上进行测试:




2019-06-02 14:25:44 qq_33765199 阅读数 791
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13376 人正在学习 去看看 郭宏志

Django服务器与App(Android)客户端的简单实现

作者是一个技术小白,这也是本人的第一篇文章,虽然网上关于Django和Android结合搭建app的文章很多,但是还是想要根据自己在搭建过程中遇到的问题写一篇学习笔记,同时也供他人借鉴一下。
说明:本示例app为本人实现 的一个很简单的记账软件,不喜勿喷。
附github地址:https://github.com/Kingqibin/paykeep

Django后台搭建

环境要求:

  1. Ubuntu 16.04 LTS 桌面版/服务器版
  2. Python 3
  3. pip等

代码实现

  1. 安装Django:
pip install django
  1. 创建django项目:
django-admin startproject paykeep # 创建项目
django-admin startapp paykeep_service # 主要的服务内容

startproject命令主要的作用是开启了一个项目的成熟框架,在之后的操作中只需要修改一下里面的参数。
startapp命令主要的功能是创建实现功能的模板。
以下在搭建时主要就是修改paykeep和paykeep_service文件夹下的主要内容。
paykeep的目录文件
paykeep_service下的文件目录结构

  1. 修改paykeep_service下的内容:

(1)修改app.py的内容:

class PaykeepServiceConfig(AppConfig):
    name = 'paykeep_service'   #修改name为你项目的名称

(2)修改model.py的内容:

from django.db import models
# 以下定义自己的类模型,以及相对应的数据段
class Pay(models.Model):
    id = models.IntegerField(null=False, primary_key=True)
    item_spend = models.CharField(null=False, max_length=50)
    money = models.FloatField(null=False)
    year = models.IntegerField(null=False)
    month = models.IntegerField(null=False)
    day = models.IntegerField(null=False)
    isPri = models.BooleanField(null=False)
    data_added = models.DateTimeField(auto_now_add=True)
# 以下的函数的作用是在展示 调试时显示相应的数据内容,可以自行配置
    def __str__(self):
        temp = "id is : " + str(self.id) + "--item is : " + str(self.item_spend)
        return temp

关于更多的类型数据定义可以自行google相关的django API。

(3)修改最重要的view.py的内容:

from django.shortcuts import render
from .models import Pay #!!!
from django.http import HttpResponse#!!!
from django.core.exceptions import ObjectDoesNotExist


def pay(request):
# 解析请求方式:
    if request.method == 'POST':
        item_spend = request.POST.get('item_spend')
        id = request.POST.get('id')
        money = request.POST.get('money')
        year = request.POST.get('year')
        month = request.POST.get('month')
        day = request.POST.get('day')
        isPri = request.POST.get('isPri')
        fun = request.POST.get('fun')
        # 功能解析
        if fun == '1':
            Pay.objects.create(id=id, item_spend=item_spend, money=money, year=year, month=month, day=day, isPri=isPri)
            try:
                t = Pay.objects.get(id=id)
                return HttpResponse("add_ok")
            except ObjectDoesNotExist:
                return HttpResponse("add_error")
        elif fun == '2':
            try:
                temp = Pay.objects.get(id=id)
                temp.delete()
                return HttpResponse("delete_ok")
            except ObjectDoesNotExist:
                return HttpResponse("not_found")
    else:#注意代码对齐
        return HttpResponse("error")

以上为本程序实现所需要的核心代码部分,其中我在使用时的django请求方式好像只能用get和post(因为我在网络方面也是小白,具体的咱也不是太清楚,感兴趣的同学可以详细研究下,看其它地博主好像可以用)。因此使用了一个比较蠢的功能解析(即传fun字段来判断要执行哪一个功能)的方式来实现。
另外在网络响应时使用的是HttpResponse具体的其它功能读者可以自行google API。

  1. 修改paykeep下的内容:

(1)修改setting.py的内容:

···
DEBUG = False
ALLOWED_HOSTS = ['*'] # 可访问的ip
···
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'paykeep_service', # 项目名字
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware', # 注释掉
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

应该只需要做以上的修改就好,具体的可以参考github的源码。

(2)修改重要的urls.py的内容:

from django.contrib import admin
from django.urls import path
from paykeep_service.views import pay

urlpatterns = [
    path('admin/', admin.site.urls),
    path('add_pay/', pay),# !!!!!!!!!!!!!!!!
]

这里的 add_pay/ 为请求方式,pay 为在view.py中定义的方式名,这里一定要对应。如果在view中写了更多的请求功能调用也可以在这里一一列明。

  1. 初始化一下数据库:
    使用manage.py文件
python manage.py migrate
  1. 运行:
python manage.py runserver 0.0.0.0:10000

允许接入的ip地址(0.0.0.0)表示允许所有的ip接入,10000端口表示开放的端口。如果使用的是云服务器,一定要在安全组里面配置一下哟。


目前为止,关于后台的搭建已经基本完成,因为我对于后台的了解也不是太多,所以讲的一些东西可能会不太准确,但是操作基本都是正确的。另外推荐大家在搭建好后台后使用postman进行一下响应的测试,看看传入响应的数据后是否会产生预期的效果,如果没用可能需要改一下代码了。防止在后面搭建完app后再反过头来修改后台,浪费时间。本人在写后台时也是经过了很长时间的调试才达到最后的效果,大家要保持耐心哟~提醒一下,如果模型更改了就要按照第5部重新部署一下数据库文件。


APP的构建(Android)

在这里假设大家对一些基础的android操作都已经很熟悉了,因此只是写一些与网络通信的介绍,其它的可以去github参照下源代码。按照国际惯例先贴代码:

// 添加支出记录:
 private void addPay(final Pay pay,final int n){
 		//开启网络传输线程------这里可以使用rxjava等热门的框架代替,这里从简
        new Thread(new Runnable() {
            @Override
            public void run() {
            	//okhttp 客户端
                OkHttpClient client = new OkHttpClient();
                //请求体----添加你需要上传的字段
                RequestBody requestBody = new FormBody.Builder()
                        .add("id",String.valueOf(pay.getId()))
                        .add("item_spend",pay.getName())
                        .add("money",String.valueOf(pay.getMoney()))
                        .add("year",String.valueOf(pay.getYear()))
                        .add("month",String.valueOf(pay.getMonth()))
                        .add("day",String.valueOf(pay.getDay()))
                        .add("isPri",pay.isPrivate()?"True":"False")
                        .add("fun",String.valueOf(1))
                        .build();
                // 请求构建  添加你自己的ip地址   另外 请求方式 add_pay 要与urls.py中定义的相同
                Request request = new Request.Builder()
                        .url("http://"+ip+"/add_pay/")
                        .post(requestBody)
                        .build();
                try {
                    Response response = client.newCall(request).execute();
                    //请求处理
                    String rd = response.body().string();
                    Log.d(TAG, "get response : "+rd);
                    if (rd.isEmpty()){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (n==1)
                                    Toast.makeText(MainActivity.this,"啊咧咧~下次再上传~",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }else {
                        if (rd.equals("add_ok")){
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    pay.setUploaded(true);
                                    pay.save();
                                    refreshSum();
                                    if (n==1)
                                        Toast.makeText(MainActivity.this,"添加成功",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if(n==1)
                                        Toast.makeText(MainActivity.this,"添加失败",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (n==1)
                                Toast.makeText(MainActivity.this,"啊咧咧~下次再上传~",Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }
	// 删除消费记录 几乎跟上面相同
    private void deletePay(final Pay pay,final int pos){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                RequestBody requestBody = new FormBody.Builder()
                        .add("id",String.valueOf(pay.getId()))
                        .add("item_spend",pay.getName())
                        .add("money",String.valueOf(pay.getMoney()))
                        .add("year",String.valueOf(pay.getYear()))
                        .add("month",String.valueOf(pay.getMonth()))
                        .add("day",String.valueOf(pay.getDay()))
                        .add("isPri",pay.isPrivate()?"True":"False")
                        .add("fun",String.valueOf(2))
                        .build();
                Request request = new Request.Builder()
                        .url("http://"+ip+"/add_pay/")
                        .post(requestBody)
                        .build();
                try {
                    Response response = client.newCall(request).execute();
                    String rd = response.body().string();
                    Log.d(TAG, "get response : "+rd);
                    if (rd.isEmpty()){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this,"啊咧咧~电波无法到达~",Toast.LENGTH_SHORT).show();
                            }
                        });
                    }else {
                        if (rd.equals("delete_ok")){
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    pays.remove(pos);
                                    adapter.notifyItemRemoved(pos);
                                    recyclerView.scrollToPosition(pos);
                                    LitePal.delete(Pay.class,pay.getId());
                                    refreshSum();
                                    Toast.makeText(MainActivity.this,"消除成功",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this,"消除失败",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this,"啊咧咧~电波无法到达~",Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        }).start();
    }

其它的一些安卓代码,大家有兴趣的话参见github,我在这里就只放核心了,如有问题可在评论区留言。


目前为止项目基本就结束了!因为写文章时离项目完成有一段时间了,所以大家如果觉得我写的有问题,不清楚的地方都可以在评论区留言,我及时修改(只要我看地到-哈哈牛逼地叉会儿腰)

转载请声明出处,谢谢

2017-07-30 20:52:53 ymeddmn 阅读数 4028
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13376 人正在学习 去看看 郭宏志

最近在学习django,就想着自己搭建一个django的服务器,自己写app的客户端,因为django是初学所以还是遇到了几个坑的废话不多先贴出项目地址:https://github.com/ymeddmn/PythonWebDemo

python群号码:387214990

django和android项目的搭建略过

服务端django的项目配置

1,首先将我们创建的app模块配置在setting这里,本例获取验证码用的是logreg模块
首先将我们创建的app模块配置在setting这里,本例获取验证码用的是logreg模块

2,host的配置如下图,此ip为本机ip地址,DEBUG=True
host的配置如下图,此ip为本机ip地址,DEBUG=True

3,将此处的依赖注释,具体原因我暂时也没有搞明白
将此处的依赖注释,具体原因我暂时也没有搞明白

4,下面看一下实现请求的代码

这里用post方法获取到请求的参数:手机号,截取前四位返回为客户端
如果请求方法错误会返回给客户端错误信息,转json的操作请看demo

from django.shortcuts import render
from django.http import HttpResponse
from app import utils, JsonUtil


def getCode(request):
    code = 200
    des = ''
    success = True;
    item = {}
    body = []
    if utils.checkRequestMethon(request, 'POST'):
        phone = request.POST.get('phone')
        resCode = phone[0:4]
        print(resCode)
        item.setdefault('checkCode', resCode)
        body.append(item)
        print(body)
    else:
        success = False
        code = 0
        des = '请求方法错误'
    if success:
        return HttpResponse(JsonUtil.toResultJson(code, body, '成功').encode('utf-8'))
    else:
        return HttpResponse(JsonUtil.toResultJson(code, body, des).encode('utf-8'))

5,Url的配置如下
Url的配置如下

note:注意转json串的时候这里记得加上ensure_ascii=False,否则客户端中文会无法显示
这里写图片描述

其他代码请看项目中的 djangoproject

客户端实现Android代码实现

客户端会在在按钮点击的时候用okhttp请求服务器获取验证码,将请求下来的结果显示到按钮上

package demo.horse.com.djangoprojectclient.logreg;

import android.Manifest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.Charset;

import demo.horse.com.djangoprojectclient.R;


public class RegesterActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnCode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_regester);
        initView();

    }

    private void initView() {
        btnCode = (Button) findViewById(R.id.btn_getcode);
        btnCode.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                FormEncodingBuilder builder = new FormEncodingBuilder();
                builder.add("phone", "13691599815");

                Request request = new Request.Builder()
                        .url("http://192.168.1.100:8000/getCode/")
                        .post(builder.build())
                        .build();
                Call call = client.newCall(request);
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure(Request request, IOException e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onResponse(Response response) throws IOException {

                        Message msg = handler.obtainMessage();
                        msg.obj = response.body().string();
                        handler.sendMessage(msg);
                    }
                });
            }
        }).start();

    }

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            String m = (String) msg.obj;
            try 
                m = URLDecoder.decode(m, "utf-8");
                btnCode.setText(m);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return false;
        }
    });
}

上面唯一需要注意的是 m = URLDecoder.decode(m, “utf-8”);
必须对请求下来的数据进行解码
对了,还要记得加上请求网络权限

下面看一下实现的效果图

请求前,button显示获取验证码
这里写图片描述

点击请求成功显示请求下来的json串
这里写图片描述

项目地址https://github.com/ymeddmn/PythonWebDemo
python群号码:387214990

2018-12-13 18:35:52 m0_37094131 阅读数 1612
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13376 人正在学习 去看看 郭宏志

上一篇讲了一下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<NameAndValue> initNameAndParams(){
        List<NameAndValue> list = new ArrayList<>();
        list.add(new NameAndValue("username" , "cx3"));
        list.add(new NameAndValue("password" , "4343543"));
        list.add(new NameAndValue("email" , "1522321800@qq.com"));
        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<NameAndValue> 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<NameAndValue> initNameAndParams(){
        List<NameAndValue> list = new ArrayList<>();
        list.add(new NameAndValue("username" , "cx3"));
        list.add(new NameAndValue("password" , "4343543"));
        list.add(new NameAndValue("email" , "1522321800@qq.com"));
        list.add(new NameAndValue("phone" , "13710651984"));
        return list;
    }
    
       public void postData(String url , List<NameAndValue> 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<List<ModelTestUser>>(){}.getType();
//                List<ModelTestUser> mApiResult = gson.fromJson(result, apiType);
            }
        });

然后再看看Fiddler 抓包的数据:
在这里插入图片描述

然后就可以从客户端中取到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<ModelPlay> list = (List<ModelPlay>) 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<List<ModelPlay>>(){}.getType();
                        List<ModelPlay> 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客户端!!!

2018-03-31 12:19:02 qq_40213521 阅读数 2061
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13376 人正在学习 去看看 郭宏志

参加一个比赛,指定用虹软的人脸识别功能,奈何虹软人脸识别要自己建人脸库,不然就只能离线用,总不能装个样子,简单看了下虹软Demo,下面决定用这种简单方法实现在线人脸识别:

    Android端(虹软Demo)取出人脸信息和姓名,人脸信息写入.data文件,存入手机本地------>取出文件上传至Python Djano后台,后台把文件保存在工程下并把路径存入数据库------>Android端访问后台接口,遍历所有数据库中文件路径然后作为参数再次访问后台,得到所有人脸信息文件和姓名,使用识别功能时,就可以开始和所有人脸信息比对,得到效果


Django 后台代码:

在工程下新建一个文件夹uploads,用来存放人脸数据.data文件

为简单实现,在setting.py中注释

#'django.middleware.csrf.CsrfViewMiddleware',
不然post请求被拦截,认真做工程不建议这样做

app.urls:

from django.conf.urls import url, include
from . import views

urlpatterns = [
    url(r'^posts',views.posttest),
    url(r'^getallface',views.getface),
    url(r'^filedown',views.file_download),
]
views.py
#coding:utf-8
import json
from imp import reload
import sys
import os
from django.http import HttpResponse, HttpResponseRedirect, StreamingHttpResponse
from django.shortcuts import render, render_to_response
from django.template import RequestContext
from faceproject.settings import BASE_DIR, MEDIA_ROOT
reload(sys)
from faceapp.models import face, Faceinfos, FaceinfoForm


def getface(request):
    if request.method=='GET':
        WbAgreementModel = Faceinfos.objects.all()
        cflist = []
        cfdata = {}
        cfdata["coding"] = 1
        cfdata['message'] = 'success'
        for wam in WbAgreementModel:
            wlist = {}
            wlist['name'] = wam.username
            wlist['faceinfo']=wam.fileinfo
            cflist.append(wlist)
        cfdata['data'] = cflist
        return HttpResponse(json.dumps(cfdata, ensure_ascii=False), content_type="application/json")

def posttest(request):
    if request.method=='POST':
        files=request.FILES['fileinfo']
        if not files:
            return HttpResponse("no files for upload!")
        Faceinfos(
            username=request.POST['username'],
            fileinfo=MEDIA_ROOT+'/'+files.name
        ).save()
        f = open(os.path.join('uploads', files.name), 'wb')
        for line in files.chunks():
            f.write(line)
            f.close()
    return HttpResponseRedirect('/face/')

def file_download(request):
    global dirs
    if request.method=='GET':
        dirs=request.GET['dirs']
    def file_iterator(file_name, chunk_size=512):
        with open(file_name) as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break

    the_file_name = dirs
    response = StreamingHttpResponse(file_iterator(the_file_name))
    return response

Android代码,使用Okhttp进行网络连接

网络访问类:

public class HttpUtil {
    public static void sendOkHttpRequestPost(String address, RequestBody requestBody, okhttp3.Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .post(requestBody)
                .build();
        client.newCall(request).enqueue(callback);
    }

    public static void sendOkHttpRequestGET(String address, okhttp3.Callback callback) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
    }

}
public class downloadf {
        private static downloadf downloadUtil;
        private final OkHttpClient okHttpClient;
        public static downloadf get() {
            if (downloadUtil == null) {
                downloadUtil = new downloadf();
            }
            return downloadUtil;
        }
        private downloadf() {
            okHttpClient = new OkHttpClient();
        }
        /**
         * @param url 下载连接
         * @param saveDir 储存下载文件的SDCard目录
         * @param listener 下载监听
         */
        public void download(final String url, final String saveDir, final OnDownloadListener listener) {
            Request request = new Request.Builder().url(url).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    // 下载失败
                    listener.onDownloadFailed();
                }
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    InputStream is = null;
                    byte[] buf = new byte[2048];
                    int len = 0;
                    FileOutputStream fos = null;
                    // 储存下载文件的目录
                    String savePath = isExistDir(saveDir);
                    try {
                        is = response.body().byteStream();
                        long total = response.body().contentLength();
                        File file = new File(savePath, getNameFromUrl(url));
                        fos = new FileOutputStream(file);
                        long sum = 0;
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                            sum += len;
                            int progress = (int) (sum * 1.0f / total * 100);
                            // 下载中
                            listener.onDownloading(progress);
                        }
                        fos.flush();
                        // 下载完成
                        listener.onDownloadSuccess();
                    } catch (Exception e) {
                        listener.onDownloadFailed();
                    } finally {
                        try {
                            if (is != null)
                                is.close();
                        } catch (IOException e) {
                        }
                        try {
                            if (fos != null)
                                fos.close();
                        } catch (IOException e) {
                        }
                    }
                }
            });
        }

        /**
         * @param saveDir
         * @return
         * @throws IOException
         * 判断下载目录是否存在
         */
        private String isExistDir(String saveDir) throws IOException {
            // 下载位置
            File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
            if (!downloadFile.mkdirs()) {
                downloadFile.createNewFile();
            }
            String savePath = downloadFile.getAbsolutePath();
            return savePath;
        }

        /**
         * @param url
         * @return
         * 从下载连接中解析出文件名
         */
        @NonNull
        private String getNameFromUrl(String url) {
            return url.substring(url.lastIndexOf("/") + 1);
        }

        public interface OnDownloadListener {
            /**
             * 下载成功
             */
            void onDownloadSuccess();

            /**
             * @param progress
             * 下载进度
             */
            void onDownloading(int progress);

            /**
             * 下载失败
             */
            void onDownloadFailed();
        }
    }
使用:

MediaType type = MediaType.parse("application/octet-stream");//"text/xml;charset=utf-8"
File file = new File(mDBPath +"/"+name+".data");
            File file1=new File(mDBPath+"/face.txt");
RequestBody fileBody = RequestBody.create(type, file);
RequestBody fileBody1 = RequestBody.create(type, file1);
RequestBody requestBody1 = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart("username",name)
      .addFormDataPart("fileinfo",name+".data",fileBody)
      .build();

HttpUtil.sendOkHttpRequestPost("http://120.79.51.57:8000/face/posts", requestBody1, new Callback() {
   @Override
   public void onFailure(Call call, IOException e) {
      Log.v("oetrihgdf","失败");
   }
   @Override
   public void onResponse(Call call, Response response) throws IOException {
      Log.v("oifdhdfg","成功");

   }

});

HttpUtil.sendOkHttpRequestGET("http://120.79.51.57:8000/face/getallface", new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String responsedata=response.body().string();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Gson gson=new Gson();
                Facelist facelist= gson.fromJson(responsedata,new TypeToken<Facelist>(){}.getType());
                faces.addAll(facelist.getData());
                Log.v("faceilist",faces.get(0).getFaceinfo());
                for (Face face:faces){
                    Log.v("orihgdofg",face.getFaceinfo());
                    downloadf.get().download("http://120.79.51.57:8000/face/filedown?"+"dir="+face.getFaceinfo(), getExternalCacheDir().getPath(), new downloadf.OnDownloadListener() {
                        @Override
                        public void onDownloadSuccess() {
                            Log.v("jmhfgh","下载完成");
                            //Utils.showToast(MainActivity.this, "下载完成");
                        }
                        @Override
                        public void onDownloading(int progress) {
                            // progressBar.setProgress(progress);
                        }
                        @Override
                        public void onDownloadFailed() {
                            Log.v("jmhfgh","下载失败");
                            // Utils.showToast(MainActivity.this, "下失败载失败");
                        }
                    });
                    FileInputStream fs = null;
                    try {
                        fs = new FileInputStream(getExternalCacheDir().getPath()+"/"+face.getName()+".data");
                        ExtInputStream bos = new ExtInputStream(fs);
                        //load version
                        byte[] version_saved = bos.readBytes();
                        FaceDB.FaceRegist frface = new FaceDB.FaceRegist(face.getName());
                        AFR_FSDKFace fsdkFace = new AFR_FSDKFace(version_saved);
                        frface.mFaceList.add(fsdkFace);
                        mResgist.add(frface);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

    }
});

没有更多推荐了,返回首页