原生API入坑指南,wordpress添加文(加文)章固定字段

让wordpress的篇章多少表
增加一个字段,使其能在篇章编辑页能编辑,并能通过rest api 获取出来。

那是一个密密麻麻文章,分3有些:
1、准备干活–Yii2高档模板的设置,以及编写一个RESTful
2、测试工作–单元测试和API测试
3、你追我赶–覆盖率、基础概念、引用文献等

原生API入坑指南,wordpress添加文(加文)章固定字段。多如牛毛文章

运用django rest framework
包装你的API

配置django rest framework jwt

  1. github下载

https://github.com/GetBlimp/django-rest-framework-jwt
  1. 进去虚拟环境

export VIRTUALENVWRAPPER_PYTHON='/usr/local/bin/python3'
export WORKON_HOME='/Users/zhouming/Documents'
source /usr/local/bin/virtualenvwrapper.sh
workon VueShop
  1. 动用pip实行设置
    pip install djangorestframework-jwt

  2. 在setting中设置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    )
}

其中

'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',

是默许的证实机制,纵然不在setting中安装,依旧会默许使用这一个表明机制。大家添加了事实上唯有'rest_framework_jwt.authentication.JSONWebTokenAuthentication'

  1. 配置url路由

from rest_framework_jwt.views import obtain_jwt_token
#...

urlpatterns = [
    '',
    # ...

    url(r'^api-token-auth/', obtain_jwt_token),
]

例:给作品加一个缩略图字段 litpic 

那是第一有些
测试此前大家有2件准备工作:一是安装Yii2高级模板,二是编辑一个RESTful。

前言

正文不会对restful等api概念举办长篇大论,意在让我们疾速上手api的开支,随着项目标充实,领导们发现到,让后端人员写前端代码是会同低效的事,于是特意给配了前端开发人士。前后端分离那种方法让大家注意于api的开发,不用考虑模板层,但写api也是有肯定技术的,我会规行矩步的从简到繁,再从繁到简的牵线django
开发api的章程。
让大家开端吧……

选拔 postman来效仿获取jwt token和token认证进程

  1. 创建jwt token
    url:
    http://127.0.0.1:8000/api-token-auth/
    post 方式
    body类型 连串化的json字符串 application/json
    body值

{
    "username": "zhouming",
    "password": "Mmix1009"
}

出口结果

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJ1c2VybmFtZSI6Inpob3VtaW5nIiwiZXhwIjoxNTE0NjU2NjE5LCJlbWFpbCI6Ijk0MDgyNTg5N0BxcS5jb20ifQ._2rHky8yHeUD9b02_Azk3lZzhO2OiWgj5s_oHShNWeY"
}
  1. 使用jwt token来请求api
    测试api,可以行使其余api,除了自己得到token的api
    http://127.0.0.1:8000/api-token-auth/
    请求那么些api服务器会输出如下响应。

{
    "username": [
        "该字段是必填项。"
    ],
    "password": [
        "该字段是必填项。"
    ]
}

俺们用goods api来做请求吧。

3.在app中倡导呼吁,抛出下边问题

RuntimeError: You called this URL via POST, but the URL doesn’t end in
a slash and you have APPEND_SLASH set.
post请求要用 /作为最终。
Post请求中缘何要抬高
[self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; // header上加入key为content-type值为application/json的项
实际上意义是为post请求添加了一个header.key 为 Content-Type
,值application/json,告诉服务器客户端是应用application/json方法举行的编码。
不过,数据发送出去,还要服务端解析成功才有含义。一般服务端语言如
php、python 等,以及它们的
framework,都放到了机关分析常见数据格式的出力。服务端常常是基于请求头(headers)中的
Content-Type
字段来获知请求中的消息主体是用何种措施编码,再对主体展开解析。所以说到
POST 提交数据方案,包涵了 Content-Type 和音讯主体编码格局两部分.

首先 通过mysql 给著作表 wp_posts 加一个字段 litpic

安装

目的是将yii2-app-advanced的测试跑起来。

1、如若你早已安装了composer,能够跳到下一步。

2、安装和配置Yii2高级模板,参看yii2-app-advanced的Install

3、近年来安装的Yii2.0.14,必要将composer.json中"codeception/verify": "~0.3.1",改为"codeception/verify": "~1.0.0",
否则会合世[Error] Class 'PHPUnit_Framework_Assert' not found。别忘了执行composer update

4、因为指出测试数据库和开发、正式环境分开。
于是要求新建数据库yii2advanced_test,然后实施php yii_test migrate。每一遍有数据库的改变都要实施五回。那也是migrate的市值展示

澳门葡京备用网址,5、执行./vendor/bin/codecept run运行测试。参看Testing

Django原生API入门

让大家先看一段代码……
以下写法有成百上千弊病:
1、数据库字段一个一个的系列化,不便宜,工作量大,不难失误
2、如果有add_time那种时刻字段,体系化的时候还会报错
3、使用HttpResponse传递json串比较费劲。
注:指出我们利用谷歌(Google)浏览器调试json代码,并在谷歌(Google)商家安装JSONView

# -*- coding: utf-8 -*-
__date__ = '2018/2/5 下午10:36'

from django.views.generic.base import View
from django.http import HttpResponse

from machines.models import Machines

import json

class MachinesView(View):
    def get(self, request):
        json_list = []
        machines = Machines.objects.all()[:100]
        for machine in machines:
            json_dict = {}
            json_dict["username"] = machine.name
            json_dict["password"] = machine.password
            json_dict["port"] = machine.port
            .........
            json_list.append(json_dict)
        return HttpResponse(json.dumps(json_list), content_type="application/json")

让大家解决弊端问题1,优化以上代码……

# -*- coding: utf-8 -*-
__date__ = '2018/2/5 下午10:36'

from django.views.generic.base import View
from django.http import HttpResponse

from machines.models import Machines

import json

from django.forms.models import model_to_dict #<<<<<<<<<<<<重点看我

class MachinesView(View):
    def get(self, request):
        json_list = []
        machines = Machines.objects.all()[:100]
        for machine in machines:
            json_dict = model_to_dict(machine) #<<<<<<<<<<<<<<重点看我
            json_list.append(json_dict) #<<<<<<<<<<<<<<重点看我
        return HttpResponse(json.dumps(json_list), content_type="application/json")

接下去解决弊端问题2,优化方面的代码……

# -*- coding: utf-8 -*-
__date__ = '2018/2/5 下午10:36'

from django.views.generic.base import View
from django.http import HttpResponse

from machines.models import Machines

import json

from django.core import serializers #<<<<<<<<<<<<<<重点看我和下面的类

class MachinesView(View):
    def get(self, request):
        machines = Machines.objects.all()[:100]
        json_data = serializers.serialize("json", machines)
        json_data = json.loads(json_data)
        return HttpResponse(json.dumps(json_data), content_type="application/json") #这里必须把json_data序列化,才能传入HttpResponse,json.dumps之后是字符串,而json.loads后是字典

为了证实json.dumps和json.loads,我临时立异了上边代码中的类,去掉冗余的一步json_data
= serializers.serialize(“json”,
machines),然后直接传json_data给HttpResponse,你也可以不看这一步,间接看解决弊端3的代码部分

class MachinesView(View):
    def get(self, request):
        machines = Machines.objects.all()[:100]
        json_data = serializers.serialize("json", machines)
        return HttpResponse(json_data, content_type="application/json")

再解决弊端问题3,优化方面的代码……

# -*- coding: utf-8 -*-
__date__ = '2018/2/5 下午10:36'

from django.views.generic.base import View
from django.http import JsonResponse #<<<<<<<<<<<重点看我

from machines.models import Machines

import json

from django.core import serializers 


class MachinesView(View):
    def get(self, request):
        machines = Machines.objects.all()[:100] #取出数据
        json_data = serializers.serialize("json", machines) #序列化
        json_data = json.loads(json_data)# 加载成字典
        return JsonResponse(json_data, safe=False) #扔出去

上面只是简短的牵线了原生API,其实有过多题材没有解决,比如动态文档问题,添加文(加文)书路径等问题,接下去自己将会重点介绍drf的选拔,来一一攻破它们。

总结

  1. 取得token的api中不能测试是还是不是用token认证
  2. debug request.user 可以赢得当前用户到底是怎样用户。

然后在焦点的function.php 后边添加如下代码:

树立一个restful的言传身教

目标是为测试准备一个格局和model,用于末端的测试。

1、增添一个用到blog(也足以定义为api等),必看Adding more
applications

别忘了执行php init对blog举行设置。
接下来一旦您的数据库配置有变动,请修改common/config/main-local.php的db。

2、执行php yii migrate/create create_news_table,新建一个news表,在console/migrations/上边多了一个好像m180228_073146_create_news_table.php的公文,添加字段

  'code' => $this->string(32)->notNull()->unique(),
  'title' => $this->string()->notNull(),
  'content' => $this->text()->null(),
  'status' => $this->smallInteger()->notNull()->defaultValue(0),
  'created_at' => $this->integer()->notNull()->defaultValue(0),
  'created_by' => $this->integer()->notNull()->defaultValue(0),
  'updated_at' => $this->integer()->notNull()->defaultValue(0),
  'updated_by' => $this->integer()->notNull()->defaultValue(0),

在common\models下新建News,也得以用gii工具生成。最简便易行的类似:

namespace common\models;
class News extends \yii\db\ActiveRecord
{ 
    public function rules()
    {
        return [
            [['code', 'title'], 'required'],
            [['content'], 'string'],
            [['status', 'created_at', 'created_by', 'updated_at', 'updated_by'], 'integer'],
            [['code'], 'string', 'max' => 32],
            [['title'], 'string', 'max' => 255],
            [['code'], 'unique'],
        ];
    }
}

别忘记执行php yii_test migrate

3、依照RESful规范新建news的CRUD,参看Rest火速入门
1)、新建控制器:

namespace blog\controllers;
use yii\rest\ActiveController;
class NewsController extends ActiveController
{
    public $modelClass = 'common\models\News';
}

2)、配置URL规则,修改blog/config/main.php

'urlManager' => [
            'enablePrettyUrl' => true,
            //'enableStrictParsing' => true,
            'showScriptName' => false,
            'rules' => [
                ['class' => 'yii\rest\UrlRule', 'controller' => 'news'],
            ],
        ],

3)、启用 JSON 输入和输出,修改blog/config/main.php

'request' => [
            //'class' => '\yii\web\Request',
            'enableCookieValidation' => false,
            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ],
],
'response' => [
            'format' => yii\web\Response::FORMAT_JSON,
            'charset' => 'UTF-8',
],

4)、利用postman检查news的restful api。

4、为了演示测试,大家在common下新建文件夹helpers,新建CustomString.php,新增一个方法。
内容如下:

namespace common\helpers;
class CustomString
{
    //生成一个code 
    public static function generateCode($length = 20, $prefix = '')
    {
        return $prefix . \Yii::$app->security->generateRandomString($length);
    }
}

并且,在common\models\news.php的rules方法后新增:

public function beforeValidate()
    {
        if (empty($this->code)) {
            $this->code = CustomString::generateCode(10, 'n');
        }
        return parent::beforeValidate();
    }

准备工作早就完毕,那里到没有啥样,就是Yii2的正规开发。

下一篇:测试工作

add_action( 'add_meta_boxes', 'myplugin_add_custom_box');


add_action( 'save_post', 'myplugin_save_postdata');

function myplugin_add_custom_box() {
add_meta_box(
'myplugin_sectionid',
'设置缩略图', // 可自行修改标题文字
'myplugin_inner_custom_box',
'post'
);
}

function myplugin_inner_custom_box( $post ) {
global $wpdb;

// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'myplugin_noncename' );

// 获取固定字段litpic的值,用于显示之前保存的值
// 此处wp_posts新添加的字段为litpic,多个用半角逗号隔开
$date = $wpdb->get_row( $wpdb->prepare( "SELECT litpic FROM $wpdb->posts WHERE ID = %d", $post->ID) );

// litpic  字段输入框的HTML代码
echo '<label for="litpic_new_field">图片url </label>';
echo '<input type="text" id="litpic_new_field" name="litpic_new_field" value="'.$date->litpic.'" size="28" />';
// 多个字段依此类推
}

function myplugin_save_postdata( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( ’DOING_AUTOSAVE’ ) && DOING_AUTOSAVE )
return;

// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename( __FILE__ ) ) )
return;

// 权限验证
if ( 'post' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}

// 获取编写文章时填写的固定字段的值,多个字段依此类推
$litpic = $_POST['litpic_new_field'];

global $wpdb;
$wpdb->update( "$wpdb->posts",
// 以下一行代码,多个字段的话参照下面的写法,单引号中是字段名,右边是变量值。半角逗号隔开
array( 'litpic' => $litpic),
array( 'ID' => $post_id ),
// 添加了多少个新字段就写多少个%s,半角逗号隔开
array( '%s'),
array( '%d')
);
}

添加后,作品页会彰显litpic字段的输入框,如图:

澳门葡京备用网址 1

但此刻 rest api还不会把litpic字段输出。

打开 /wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
文件。

加上如下代码:

if ( ! empty( $schema['properties']['litpic'] ) ) {
            $data['litpic'] = $post->litpic;
        }

'litpic'        => array(
                    'description' => __( 'A litpic to protect access to the content and excerpt.' ),
                    'type'        => 'string',
                    'context'     => array( 'view', 'edit', 'embed' ),
                ),

$post_type_attributes = array(
            'title',
            'editor',
            'author',
            'excerpt',
            'thumbnail',
            'comments',
            'revisions',
            'page-attributes',
            'post-formats',
            'custom-fields',
            'litpic',
        );
        $fixed_schemas = array(
            'post' => array(
                'title',
                'editor',
                'author',
                'excerpt',
                'thumbnail',
                'comments',
                'revisions',
                'post-formats',
                'custom-fields',
                'litpic',
            ),

case 'litpic':
                    $schema['properties']['litpic'] = array(
                        'description' => __( 'The ID for the litpic of the object.' ),
                        'type'        => 'string',
                        'context'     => array( 'view', 'edit', 'embed' ),
                    );
                    break;

现在,rest api 就足以把litpic 字段输出了。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website