Django 사용자 정의 YamlField 구현 프로세스 분석
djangoadmin을 사용할 때 백그라운드의 Textarea 여러 줄 텍스트 상자는 yaml 형식으로 작성할 수 있으며, 데이터베이스는 Text 텍스트 형식으로 저장되며, 필드와 인터페이스에서 읽으면 자동으로 사전이나 목록 형식으로 변경됩니다.
pip installdjango-yamlfied를 사용해 보았습니다. 새 버전django를 수정한 후
인터페이스에서 되돌아오는 필드는 문자열 형식으로 예상에 부합되지 않습니다.
전에 한 판 썼어요.
import yaml
from django.db import models
class YamlField(models.TextField):
def to_python(self, value): # python
if not value:
value = {}
if isinstance(value, (list, dict)):
return value
return yaml.safe_load(value)
def get_prep_value(self, value): # create ,
return value if value is None else yaml.dump(value, default_flow_style=False)
def from_db_value(self, value, expression, connection): #
return self.to_python(value)
문제는 입력 상자 입력- a
- b
- c
저장하면 사전의 문자열 형식으로 바뀝니다.
['a','b','c']
원형으로 보존할 수 없어 연구를 거듭한 후django-jsonfield를 참고하여 한 판을 썼다.
원리는 계승 모델로 바꾸는 것이다.Field 클래스, (models.TextField 클래스를 계승하면 formfield 및value_to_string이 적용되지 않음)
데이터베이스는 데이터베이스에 있는yaml 텍스트를dict/list로 바꾸고djangoadmin에서 사용자 정의widget을 통해yaml 문자열 형식으로 표시합니다.
저장할 때, 폼의 yaml 문자열 형식이 정확한지 확인하기 위해서, 폼을 사용자 정의해야 합니다.전체 코드는 다음과 같습니다.
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): # python
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)): # ,
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): #
return self.to_python(value)
def value_to_string(self, obj): # Rest Framework
return self.value_from_object(obj)
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.