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转换为字符串
/polls/fields.py

 

二、 使用自定义的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
/polls/models.py
 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('/')
/polls/views.py
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 ]
/polls/urls.py

 

三、 使用自定义的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
/polls/fields.py
 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
/polls/models.py
1 class AddPdfForm(forms.ModelForm):
2     class Meta:
3         model = AddPdfFileModel
4         fields = ['name','file']
/polls/forms.py
 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()})
/polls/views.py
 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>
/polls/templates/add_file.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 ]
/polles/urls.py

 

posted @ 2017-05-30 12:05  taibai  阅读(473)  评论(0)    收藏  举报