一、实战应用技巧— models中某些字段的使用
文件上传FileField与ImageField字段的使用:
1.在setting.py文件中设置媒体根路径以及访问路径,代码如下:
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2.在url.py中配置跟路由,注意不是分路由,并不是某个app对应的路由,代码如下:
from django.contrib import admin from django.urls import path from django.conf.urls import url from family_temple.settings import MEDIA_ROOT from django.views.static import serve urlpatterns = [ path('admin/', admin.site.urls), url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}) ]
用来图片回显,与查看图片。
3.文件的存储,直接将文件放入对应的字段名中,django会自动存储,再将存储的路径作为值存入数据库。
class UserInfo(AbstractUser): #用户表;扩展字段,继承AbstractUser类, '''用户信息''' nid = models.AutoField(primary_key=True) telephone = models.CharField(max_length=11, null=True, unique=True) #这些字段接收一个字符串就可以了 avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") #而它一定要接收一个文件对象 avatar_obj = request.FILES.get("avatar") user_obj = UserInfo.objects.create_user(username = user, password = pwd, email = email, avatar = avatar_obj)#这里avatar一定要接收一个文件对象 Django会实现: 会将文件对象下载到项目的根目录中avatars文件夹中(如果没有avatar文件夹,Django会自动创建),user_obj的avatar存的是文件的相对路径。
4.自定义图片上传路径和上传文件名:
def generate_filename(self, instance, filename): """ Apply (if callable) or prepend (if a string) upload_to to the filename, then delegate further processing of the name to the storage backend. Until the storage layer, all file paths are expected to be Unix style (with forward slashes). """ if callable(self.upload_to): filename = self.upload_to(instance, filename) else: dirname = datetime.datetime.now().strftime(self.upload_to) filename = posixpath.join(dirname, filename) return self.storage.generate_filename(filename)
上面的代码是django中对ImageField上传时,生成文件名的处理方式。如果 upload_to 的参数是可调用的,则直接调用来生成文件名(包括静态文件夹后的文件路径)。要自定义上传文件名就从这里着手。
import uuid from django.db import models def image_upload_to(instance, filename): return 'original_image/{uuid}/{filename}'.format(uuid=uuid.uuid4().hex, filename=filename) class TestImageUpload(models.Model): image = models.ImageField(upload_to=image_upload_to)
按照上面的方式,就可以按照自己的意愿随意的处理文件名了(函数的参数个数是固定的)。
5.可自定义选择存储方式,在幕后,Django 将文件存储的方式和位置交给文件存储系统。它是一个对象,能真正理解文件系统、打开和读取文件等等。
Django 的默认文件储存由DEFAULT_FILE_STORAGE设置提供;如果你没有显式提供一个储存系统,就会使用它。
内建的文件系统存储类:
Django 自带django.core.files.storage.FileSystemStorage 类,它实现了基本的本地文件系统中的文件储存。
例如,下面的代码会在 /media/photos 目录下储存上传的文件,无论MEDIA_ROOT设置是什么:
from django.db import models from django.core.files.storage import FileSystemStorage fs = FileSystemStorage(location='/media/photos') class Car(models.Model): ... photo = models.ImageField(storage=fs)
自定义储存系统以相同方式工作:你可以把它们作为storage参数传递给FileField
自定义存储方式需要继承Storage类,必须实现_open()和_save()方法,以及其他的和你存储类相关的方法,请参考
多选字段的使用:
如果项目有多选的需求,但django的Model中没有多选这个字段,一般的处理方式建立一张选择项的表,然后与选择项表进行多对多处理,这样会多出很多存储多对多关系的第三张表,这种方式太浪费资源了,django-multiselectfield就为我们解决了这个问题。
1.下载
pip install django-multiselectfield
2.使用
需求:一个人又会汉语,又会英语。
那么choices属性就不能达到我们的目的了,那么久可以使用MultiSelectField来实现了,例如
from multiselectfield import MultiSelectField
class person(odels.Model): language_choices= ((‘chinese‘,u‘汉语‘), (‘english‘,u‘英语‘),(‘french‘,‘法语‘)) language = MultiSelectField(u"使用语言",choices=language_choices)
需要注意的几点:
1.MultiSelectField不支持list_display,如果在list_display中添加MultiSelectField的项就会出现报错,所以当你想在admin页管理你的数据库资料时,不能在查看页面查看到MultiSelectField的项的内容。
2.当你想使用form直接在前端生成编辑或查看数据库内容的页面时,MultiSelectField的项不能直接显示出来,而是需要进行特殊的处理,其格式如下(其中provider表示query对象,field表示MultiSelectField项)
{% for value, text in providers.field.choices %} <div class="ui slider checkbox"> <input id="id_providers_{{ forloop.counter0 }}" name="{{ form.providers.name }}" type="checkbox" value="{{ value }}"{% if value in checked_providers %} checked="checked"{% endif %}> <label>{{ text }}</label> </div> {% endfor %}
3.在使用filter对MultiSelectField项进行查询时需要注意MultiSelectField项在数据库内存的是一个列表类型的数据,如果查询选择的项和你的查询条件完全相同的数据直接使用
models.Person.objects.filter(language=[‘chinese‘])
但如果想要filter到所有选择了其中一个选项的数据(包括只选择了该选项的数据和同时选择了该选项和其他选项的数据),直接使用django提供的查询方法就不行了,那么可以使用Q语句来实现查询,其形式为
models.persom.objects.filter( Q(language=‘chinese‘)|Q(language__startswith=‘chinese,‘)|Q(language__endswith=‘,chinese‘)|Q(language__contains = ‘,chinese,‘)
DangoUeditor富文本编辑器的使用:
1.下载
pip install DjangoUeditor
2.在Django中安装DjangoUeditor 在INSTALL_APPS里面增加DjangoUeditor app,如下: INSTALLED_APPS = ( #........ 'DjangoUeditor', )
3.配置urls url(r'^ueditor/',include('DjangoUeditor.urls' )),
4.在models中的使用
C_Introduce = UEditorField(width=500, height=300, toolbars="full", imagePath="images/"+datetime.datetime.now().strftime("%Y/%m/%d")+"/%(datetime)s.%(extname)s", filePath="files/"+datetime.datetime.now().strftime("%Y/%m/%d")+"/%(datetime)s.%(extname)s", upload_settings={"imageMaxSize":1204000}, settings={}, verbose_name='简介')
5.具体内容参见官方文档
6.admin效果