知識(shí)點(diǎn)
- 什么時(shí)候需要自定義Field
- 如何自定義Field
- 舉例
簡(jiǎn)介
什么時(shí)候需要自定義Field
Django 的官方Model里提供了很多的 Field扮匠,但是有時(shí)候還是不能滿足我們的需求
如何自定義Field
根據(jù)需要子類化Field或者Field子類,實(shí)現(xiàn)序列化和反序列化
舉例
- 子類化Field
- 子類化FileField
參考文檔
實(shí)驗(yàn)步驟
自定義一個(gè)ListField的類
【fields.py】
from django.db import models
import ast
# 自定義一個(gè)ListFiled,繼承與TextField這個(gè)類
class ListFiled(models.TextField):
description = "just a listfiled"
# 繼承TextField
def __init__(self, *args, **kwargs):
super(ListFiled, self).__init__(*args, **kwargs)
# 讀取數(shù)據(jù)庫(kù)的時(shí)候調(diào)用這個(gè)方法
def from_db_value(self, value, expression, conn, context):
print('from_db_value')
if not value:
value = []
if isinstance(value, list):
return value
print('value type ', type(value))
# 直接將字符串轉(zhuǎn)換成python內(nèi)置的list
return ast.literal_eval(value)
# 保存數(shù)據(jù)庫(kù)的時(shí)候調(diào)用這個(gè)方法
def get_prep_value(self, value):
print("get_prep_value")
if not value:
return value
print('value type ', type(value))
return str(value)
【models.py】
from django.db import models
from .fields import ListFiled
class ListTest(models.Model):
labels = ListFiled()
def __str__(self):
return "%s " % self.labels
【views.py】
rom django.shortcuts import render,HttpResponseRedirect
from .models import ListTest
# Create your views here.
def home(request):
return render(request, 'home.html')
def testlist(req):
# 存入數(shù)據(jù)庫(kù)測(cè)試
test = ListTest()
test.labels = ["python", "django"]
test.labels.append("allen")
test.save()
# 讀取數(shù)據(jù)庫(kù)測(cè)試
obs = ListTest.objects.all()
for ob in obs:
print((ob.labels))
return HttpResponseRedirect("/")
【urls.py】
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^testlist/', views.testlist, name='testlist'),
]
注意:數(shù)據(jù)庫(kù)同步【此步驟略】
結(jié)果顯示如下
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
get_prep_value
value type <class 'list'>
from_db_value
value type <class 'str'>
['python', 'django', 'allen']
文件類型的FileField
【add_file.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
<label>addfiles:</label>
{{ form.as_p }}
<input type="submit" value="ok">
</form>
</body>
</html>
【fields.py】
from django.db.models import FileField
from django.forms import forms
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _
class ContextTypeRestrictedFileField(FileField):
def __init__(self, content_type=None, max_upload_size=None, **kwargs):
self.content_type = content_type
self.max_upload_size = max_upload_size
super(ContextTypeRestrictedFileField, self).__init__(**kwargs)
def clean(self, *args, **kwargs):
data = super(ContextTypeRestrictedFileField, self).clean(*args, **kwargs)
file = data.file
try:
type = file.content_type
if type != self.content_type:
raise forms.ValidationError('pls upload right filetype')
if file.size > self.max_upload_size:
raise forms.ValidationError('exceed max uploadsize')
except AttributeError:
print("error")
pass
return data
【models.py】
from django.db import models
from .fields import ContextTypeRestrictedFileField
class AddPdfFileModel(models.Model):
name = models.CharField(max_length=100)
file = ContextTypeRestrictedFileField(content_type='application/pdf', max_upload_size=5242880, upload_to='pdf')
def __str__(self):
return self.name
【views.py】
from django.shortcuts import render
from .models import AddPdfFileModel
from .forms import AddPdfForm
def addfile(req):
if req.method == 'POST':
form = AddPdfForm(req.POST, req.FILES)
if not form.is_valid():
print(form.errors)
return HttpResponseRedirect("/")
name = form.cleaned_data['name']
file = form.cleaned_data['file']
add_pdf_model = AddPdfFileModel(name=name, file=file)
add_pdf_model.save()
print('success')
return render(req, 'add_file.html', {'form': AddPdfForm()})
else:
return render(req, 'add_file.html', {'form':AddPdfForm()})
【urls.py】
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^addfile/', views.addfile, name='addfile'),
]
注意:數(shù)據(jù)庫(kù)同步【此步驟略】