欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django自定義YamlField實現(xiàn)過程解析

 更新時間:2020年11月11日 10:08:26   作者:臨淵  
這篇文章主要介紹了Django自定義YamlField實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

需求

在使用django admin時希望后臺的Textarea多行文本框可以按yaml格式編寫,數(shù)據(jù)庫保存為Text文本類型,字段和接口中讀取出來自動變?yōu)樽值浠蛄斜砀袷健?br />

試過pip install django-yamlfied,修改支持新版django之后

接口中返回的字段是字符串形式,不符合預(yù)期。

之前寫過一版。

import yaml
from django.db import models

class YamlField(models.TextField):
  def to_python(self, value): # 將數(shù)據(jù)庫內(nèi)容轉(zhuǎn)為python對象時調(diào)用
    if not value:
      value = {}
    if isinstance(value, (list, dict)):
      return value
    return yaml.safe_load(value)

  def get_prep_value(self, value): # create時插入數(shù)據(jù), 轉(zhuǎn)為字符串存儲
    return value if value is None else yaml.dump(value, default_flow_style=False)

  def from_db_value(self, value, expression, connection): # 從數(shù)據(jù)庫讀取字段是調(diào)用
    return self.to_python(value)

問題是輸入框輸入

- a
- b
- c

保存后就會變成字典的字符串形式

['a','b','c']

無法原樣保存,反復(fù)研究后,參考django-jsonfield寫了一版。

原理是,改為繼承models.Field類,(繼承models.TextField類,則formfield和value_to_string不生效)

數(shù)據(jù)庫依舊將數(shù)據(jù)庫中的yaml文本轉(zhuǎn)為dict/list,在django admin中通過自定義widget顯示為yaml字符串格式。

為了保存時,驗證表單中yaml字符串格式是否正確,還需要自定義一個form。完整代碼如下。

import django
from django.db import models
from django import forms
from django.core.exceptions import ValidationError
import yaml


class YamlWidget(forms.Textarea):
  def render(self, name, value, attrs=None, renderer=None):
    if value is None:
      value = ""
    if not isinstance(value, str):
      value = yaml.safe_dump(value, default_flow_style=False)
    if django.VERSION < (2, 0):
      return super().render(name, value, attrs)
    return super().render(name, value, attrs, renderer)


class YamlFormField(forms.CharField):
  empty_values = [None, '']

  def __init__(self, *args, **kwargs):
    if 'widget' not in kwargs:
      kwargs['widget'] = YamlWidget
    super().__init__(*args, **kwargs)

  def to_python(self, value):
    if isinstance(value, str) and value:
      try:
        return yaml.safe_load(value)
      except Exception as exc:
        raise forms.ValidationError('Yaml decode error: %s' % (exc.args[0],))
    else:
      return value

  def validate(self, value):
    if value in self.empty_values and self.required:
      raise forms.ValidationError(self.error_messages['required'], code='required')


class YamlField(models.Field):
  description = "Yaml object"

  def get_internal_type(self):
    return 'TextField'

  def formfield(self, **kwargs):
    defaults = {
      'form_class': YamlFormField,
      'widget': YamlWidget
    }
    defaults.update(**kwargs)
    return super().formfield(**defaults)

  def to_python(self, value: str): # 將數(shù)據(jù)庫內(nèi)容轉(zhuǎn)為python對象時調(diào)用
    if value is None:
      if not self.null and self.blank:
        return ""
      return None
    if isinstance(value, (list, dict)):
      return value
    value = yaml.safe_load(value)
    return value

  def validate(self, value, model_instance): # 驗證從接受到字典格式
    if not self.null and value is None:
      raise ValidationError(self.error_messages['null'])
    try:
      self.get_prep_value(value)
    except ValueError:
      raise ValidationError(self.error_messages['invalid'] % value)

  def get_prep_value(self, value: (list, dict)): # 保存時插入數(shù)據(jù), 轉(zhuǎn)為字符串存儲
    if value is None:
      return None
    value = yaml.safe_dump(value, default_flow_style=False)
    return value

  def from_db_value(self, value: str, expression, connection, *args, **kwargs): # 從數(shù)據(jù)庫讀取字段是調(diào)用
    return self.to_python(value)

  def value_to_string(self, obj): # Rest Framework調(diào)用時
    return self.value_from_object(obj)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python reverse反轉(zhuǎn)部分數(shù)組的實例

    python reverse反轉(zhuǎn)部分數(shù)組的實例

    今天小編就為大家分享一篇python reverse反轉(zhuǎn)部分數(shù)組的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • Python 中的結(jié)構(gòu)模式匹配及重要性

    Python 中的結(jié)構(gòu)模式匹配及重要性

    這篇文章主要介紹了Python 中的結(jié)構(gòu)模式匹配,本篇文章介紹結(jié)構(gòu)模式匹配及其在 Python 中的重要性,它還使用不同的模式來演示如何使用 match … case 語句,需要的朋友可以參考下
    2023-06-06
  • Python圖像處理之簡單畫板實現(xiàn)方法示例

    Python圖像處理之簡單畫板實現(xiàn)方法示例

    這篇文章主要介紹了Python圖像處理之簡單畫板實現(xiàn)方法,結(jié)合實例形式分析了Python基于cv2模塊與numpy模塊的數(shù)值計算及矩形圖形繪制簡單操作技巧,需要的朋友可以參考下
    2018-08-08
  • 如何利用Python識別圖片中的文字詳解

    如何利用Python識別圖片中的文字詳解

    不知道大家有沒有遇到過這樣的問題,就是在某個軟件或者某個網(wǎng)頁里面有一篇文章,你非常喜歡,但是不能復(fù)制.這個時候我們就會選擇截圖保存,但是當(dāng)我們想用到里面的文字時,還是要一個字一個字打出來,那么能不能直接識別圖片中的文字呢?答案是肯定的,需要的朋友可以參考下
    2021-05-05
  • Python Mysql數(shù)據(jù)庫操作 Perl操作Mysql數(shù)據(jù)庫

    Python Mysql數(shù)據(jù)庫操作 Perl操作Mysql數(shù)據(jù)庫

    python對mysql數(shù)據(jù)庫的一些操作實現(xiàn)代碼
    2009-01-01
  • 使用python編寫android截屏腳本雙擊運行即可

    使用python編寫android截屏腳本雙擊運行即可

    使用python編寫一個截屏的腳本,雙擊運行腳本就OK,截屏成功后會將截屏文件已當(dāng)前時間命名,并保存在存放腳本的當(dāng)前路徑的screenshot文件夾下
    2014-07-07
  • Python?基于TCP?傳輸協(xié)議的網(wǎng)絡(luò)通信實現(xiàn)方法

    Python?基于TCP?傳輸協(xié)議的網(wǎng)絡(luò)通信實現(xiàn)方法

    網(wǎng)絡(luò)編程指在網(wǎng)絡(luò)環(huán)境中,如何實現(xiàn)不在同一物理位置中的計算機之間進行數(shù)據(jù)通信,本文重點給大家介紹Python?基于TCP?傳輸協(xié)議的網(wǎng)絡(luò)通信實現(xiàn)方法,感興趣的朋友跟隨小編一起看看吧
    2022-02-02
  • Python實現(xiàn)SSH遠程登陸,并執(zhí)行命令的方法(分享)

    Python實現(xiàn)SSH遠程登陸,并執(zhí)行命令的方法(分享)

    下面小編就為大家?guī)硪黄狿ython實現(xiàn)SSH遠程登陸,并執(zhí)行命令的方法(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳解Django通用視圖中的函數(shù)包裝

    詳解Django通用視圖中的函數(shù)包裝

    這篇文章主要介紹了詳解Django通用視圖中的函數(shù)包裝,Django是最具人氣的Python web開發(fā)框架,需要的朋友可以參考下
    2015-07-07
  • Python進階:生成器 懶人版本的迭代器詳解

    Python進階:生成器 懶人版本的迭代器詳解

    這篇文章主要介紹了Python進階:生成器 懶人版本的迭代器詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-06-06

最新評論