Django 进阶 之 自定义Field
Django的models中已经给出了很多类型的Field字段,但实际应用中还是会有些字段不能满足需求,这时可以根据需要自定义Field
定义方式: 根据需要子类化Field或者Field子类,实现序列号和反序列化
一、 自定义Field类
1 from django.db import models 2 import ast 3 4 class ListField(models.TextField): 5 description = 'just a listfield' 6 7 def __init__(self, *args, **kwargs): 8 super(ListField, self).__init__(*args, **kwargs) 9 10 def from_db_value(self,value, expression, conn, context): 11 print('from_db_value') 12 if not value: 13 value=[] 14 if isinstance(value, list): 15 return value 16 print('value type ', type(value)) 17 return ast.literal_eval(value) #把字符串转成python内置的list 18 19 # save to db will call it 20 def get_prep_value(self, value): 21 print('get_prep_value') 22 if not value: 23 return value 24 print('value type ',type(value)) 25 return str(value) #把list转换为字符串
二、 使用自定义的Field
1 from django.db import models 2 from .fields import ListField 3 4 class ListTest(models.Model): 5 labels = ListField() 6 7 def __str__(self): 8 return "%s " % self.labels
1 def addlist(request): 2 test = ListTest() 3 test.labels = ['python','django'] 4 test.save() 5 return redirect('/testlist/') 6 7 def testlist(request): 8 obs = ListTest.objects.all() 9 for ob in obs: 10 print(ob.labels) 11 return redirect('/')
1 from django.conf.urls import url 2 from . import views 3 4 urlpatterns = [ 5 url(r'^$', views.home, name='home'), 6 url(r'^addlist/$', views.addlist), 7 url(r'^testlist/$', views.testlist), 8 ]
三、 使用自定义的File字段
1 from django.db.models import FileField 2 from django.forms import forms 3 from django.template.defaultfilters import filesizeformat 4 from django.utils.translation import ungettext_lazy as _ 5 6 class ContextTypeRestrictedFileField(FileField): 7 def __init__(self, content_type=None, max_upload_size=None, **kwargs): 8 self.content_type = content_type 9 self.max_upload_size = max_upload_size 10 super(ContextTypeRestrictedFileField, self).__init__(**kwargs) 11 12 def clean(self, *args, **kwargs): 13 data = super(ContextTypeRestrictedFileField, self).clean(*args, **kwargs) 14 file = data.file 15 try: 16 type = file.content_type 17 if type != self.content_type: 18 raise forms.ValidationError('Pls upload right filetype') 19 if file.size > self.max_upload_size: 20 raise forms.ValidationError('exceed max uploadsize') 21 except AttributeError: 22 print('error') 23 return data
1 class AddPdfFileModel(models.Model): 2 name = models.CharField(max_length=100) 3 file = ContextTypeRestrictedFileField(content_type='application/pdf' 4 ,max_upload_size=5242880 5 ,upload_to='pdf' 6 ) 7 8 9 def __str__(self): 10 return self.name
1 class AddPdfForm(forms.ModelForm): 2 class Meta: 3 model = AddPdfFileModel 4 fields = ['name','file']
1 from .forms import AddPdfForm 2 from .models import AddPdfFileModel 3 4 def addfile(request): 5 if request.method == 'POST': 6 form = AddPdfForm(request.POST, request.FILES) 7 if not form.is_valid(): 8 print(form.errors) 9 return redirect('/addfile/') 10 name = form.cleaned_data['name'] 11 file = form.cleaned_data['file'] 12 add_pdf_model = AddPdfFileModel(name=name, file=file) 13 add_pdf_model.save() 14 return redirect('/') 15 else: 16 return render(request,'add_file.html',{'form':AddPdfForm()})
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Django进阶-文件上传</title> 6 </head> 7 <body> 8 <form action="." method="post" enctype="multipart/form-data"> 9 <label>addfiles:</label> 10 {{ form.as_p }} 11 <input type="submit" value="OK!"> 12 </form> 13 </body> 14 </html>
1 from django.conf.urls import url 2 from . import views 3 4 urlpatterns = [ 5 url(r'^$', views.home, name='home'), 6 url(r'^addfile/$', views.addfile), 7 ]

浙公网安备 33010602011771号