最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2020年11月11日 10:08:26   作者:臨淵  
這篇文章主要介紹了Django自定義YamlField實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(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字符串格式。

為了保存時,驗(yàn)證表單中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): # 驗(yàn)證從接受到字典格式
    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腳本操作MongoDB的教程

    使用Python腳本操作MongoDB的教程

    這篇文章主要介紹了使用Python腳本操作MongoDB的教程,MongoDB作為非關(guān)系型數(shù)據(jù)庫得到了很大的宣傳力度,而市面上的教程一般都是講解JavaScript的腳本操作,本文則是基于Python,需要的朋友可以參考下
    2015-04-04
  • python數(shù)據(jù)可視化之matplotlib.pyplot基礎(chǔ)以及折線圖

    python數(shù)據(jù)可視化之matplotlib.pyplot基礎(chǔ)以及折線圖

    不論是數(shù)據(jù)挖掘還是數(shù)據(jù)建模,都免不了數(shù)據(jù)可視化的問題,對于Python來說,Matplotlib是最著名的繪圖庫,它主要用于二維繪圖,這篇文章主要給大家介紹了關(guān)于python數(shù)據(jù)可視化之matplotlib.pyplot基礎(chǔ)以及折線圖的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • python中子類調(diào)用父類函數(shù)的方法示例

    python中子類調(diào)用父類函數(shù)的方法示例

    Python中類的初始化方法是__init__(),因此父類、子類的初始化方法都是這個,下面這篇文章主要給大家介紹了關(guān)于python中子類調(diào)用父類函數(shù)的方法示例,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-08-08
  • Python中的三目(元)運(yùn)算符詳解

    Python中的三目(元)運(yùn)算符詳解

    這篇文章主要介紹了python 三元運(yùn)算符使用解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-09-09
  • python分分鐘繪制精美地圖海報

    python分分鐘繪制精美地圖海報

    基于Python中諸如matplotlib等功能豐富、自由度極高的繪圖庫,我們可以完成各種極富藝術(shù)感的可視化作品,關(guān)于這一點(diǎn)我在系列文章在模仿中精進(jìn)數(shù)據(jù)可視化中已經(jīng)帶大家學(xué)習(xí)過很多案例了
    2022-02-02
  • Python的條件語句與運(yùn)算符優(yōu)先級詳解

    Python的條件語句與運(yùn)算符優(yōu)先級詳解

    這篇文章主要介紹了Python的條件語句與運(yùn)算符優(yōu)先級,是Python入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • Django中的文件的上傳的幾種方式

    Django中的文件的上傳的幾種方式

    這篇文章主要介紹了Django中的文件的上傳的幾種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Python多進(jìn)程同步Lock、Semaphore、Event實(shí)例

    Python多進(jìn)程同步Lock、Semaphore、Event實(shí)例

    這篇文章主要介紹了Python多進(jìn)程同步Lock、Semaphore、Event實(shí)例,Lock用來避免訪問沖突、Semaphore用來控制對共享資源的訪問數(shù)量、Event用來實(shí)現(xiàn)進(jìn)程間同步通信,需要的朋友可以參考下
    2014-11-11
  • 詳解Open Folder as PyCharm Project怎么添加的方法

    詳解Open Folder as PyCharm Project怎么添加的方法

    這篇文章主要介紹了詳解Open Folder as PyCharm Project怎么添加的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Python+Turtle制作海龜迷宮小游戲

    Python+Turtle制作海龜迷宮小游戲

    這篇文章主要是帶大家寫一個利用Turtle庫制作的一款海龜闖關(guān)的三大迷宮,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定幫助,感興趣的可以了解一下
    2022-04-04

最新評論

若尔盖县| 长沙市| 井冈山市| 大城县| 上林县| 石嘴山市| 宁河县| 天台县| 宁安市| 宜兰县| 宜宾县| 临城县| 丰原市| 本溪市| 永德县| 盈江县| 上饶市| 盖州市| 宿州市| 加查县| 龙里县| 常山县| 祁门县| 陆良县| 阿拉善左旗| 柞水县| 双鸭山市| 塘沽区| 兴和县| 南开区| 巴塘县| 伊吾县| 阿合奇县| 乌海市| 丽江市| 松潘县| 望江县| 米林县| 阿城市| 岗巴县| 太谷县|