Mih*_*fir 4 python django django-models filefield imagefield
我有这个型号:
class UserProfile(models.Model):
#..........
photo = models.ImageField(upload_to = get_upload_file_name,
storage = OverwriteStorage(),
blank = True, null = True,
height_field = 'photo_height',
width_field = 'photo_width')
Run Code Online (Sandbox Code Playgroud)
这是我的存储功能:
class OverwriteStorage(FileSystemStorage):
def _save(self, name, content):
self.delete(r'.*')
return super(OverwriteStorage, self)._save(name, content)
def get_available_name(self, name):
return name
Run Code Online (Sandbox Code Playgroud)
我该怎么做以下两件事:
每当用户上传文件(即图像)时,我想删除旧文件,无论名称是否相同.我试图删除任何与上述正则表达式匹配的内容,但这不起作用.
如果用户上传名为"me.jpg"的图像,我想以不同的方式重命名,具体取决于用户的用户名.所以我会做一些像这样做的事情return super(OverwriteStorage, self)._save(SOMETHING_ELSE_HERE, content)?我可以将其他参数传递给OverwriteStorage函数吗?
还有第三个问题:我为这个表单创建了一个ModelForm.因此用户可以上传图像.因此,当有人按下"选择文件"时,会弹出一个窗口窗口以浏览和选择照片.我怎么才能在这里显示某些文件?(例如,只有.jpg和.jpeg文件)
谢谢!
编辑:该get_upload_file_name功能
def get_upload_file_name(instance, filename):
return "%s/%s/profile_photo/%s" % (instance.user.username[0].lower(), instance.user.username, filename)
Run Code Online (Sandbox Code Playgroud)
编辑2:我已经包含了我的models.py
import datetime
import os
import urllib2, urlparse
import re
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
from django.core.files.storage import FileSystemStorage
from django.contrib.staticfiles import finders
from django.conf import settings
from django.core.files.base import ContentFile
from django.forms import widgets
now = datetime.datetime.now()
def get_upload_file_name(instance, filename):
now = datetime.datetime.now()
file_name = str(now.year) + '_' + \
str(now.month) + '_' + \
str(now.day) + '_' + \
str(now.hour) + '_' + \
str(now.minute)+ '_' + \
str(now.second)+ '.' + \
filename.split('.')[-1]
return "%s/%s/profile_photo/%s" % (instance.user.username[0].lower(),
instance.user.username,
file_name)
class OverwriteStorage(FileSystemStorage):
def _save(self, name, content):
self.delete(name)
return super(OverwriteStorage, self)._save(name, content)
class UserProfileManager(models.Manager):
def create_user_profile(self, user):
user_profile = self.create(user = user)
return user_profile
class UserProfile(models.Model):
### it is now.year - 13 because legitimate persons on this website should be over 14 years old
YEARS = tuple(
zip([format(x,'04d') for x in range(now.year-120, now.year-13)],
[format(x,'04d') for x in range(now.year-120, now.year-13)]
)
)
MONTHS = (
('January','January'),('February','February'),('March','March'),('April','April'),
('May','May'), ('June','June'),('July','July'),('August','August'),
('September','September'),('October','October'),('November','November'), ('December', 'December')
)
GENDERS = (('M', 'Male'), ('F', 'Female'))
user = models.OneToOneField(User, related_name = 'MoreAboutUser', unique=True, verbose_name=_('user'))
year_of_birth = models.CharField(max_length=10, blank = True, null = True, choices=YEARS)
month_of_birth = models.CharField(max_length=10, blank = True, null = True, choices=MONTHS)
gender = models.CharField(max_length=1, blank = True, null = True, choices=GENDERS)
photo = models.ImageField(upload_to = get_upload_file_name,
blank = True, null = True,
height_field = 'photo_height',
width_field = 'photo_width',
#widget = widgets.FileInput(attrs={'accept': 'image/gif,image/png,image/jpeg'})
)
photo_height = models.PositiveIntegerField(blank = True, default = 0)
photo_width = models.PositiveIntegerField(blank = True, default = 0)
creation_time = models.DateTimeField(auto_now_add = True, auto_now = False)
update_time = models.DateTimeField(auto_now_add = False, auto_now = True)
class Meta:
verbose_name = _('user profile')
verbose_name_plural = _('user profiles')
def __unicode__(self):
return self.user.username
objects = UserProfileManager()
def get_profile_photo_url(self):
if self.photo and hasattr(self.photo, 'url'):
return self.photo.url
else:
return '/static/images/generic_profile_photo.jpg'
def create_user_profile(sender, instance, created, **kwargs):
if created:
try:
profile = UserProfile.objects.create_user_profile(user = instance)
profile.save()
except:
pass
post_save.connect(create_user_profile, sender=User)
Run Code Online (Sandbox Code Playgroud)
存储API对您的模型一无所知,因此不能考虑其他字段的值 - 它不知道存储在该字段中的旧文件的名称,也不知道哪个用户拥有模型记录.
你似乎走在正确的轨道上为upload_to = get_upload_file_name你提供了一个选择ImageField; 该get_upload_file_name功能(你有没有在你的问题发布)将能够构建基于用户的文件名的图像,因为它得到的模型实例的引用,因此它知道谁拥有模型实例的用户.
至于删除旧文件,您可能需要在模型的save()方法中实现它.此时从现有模型实例中找到旧文件名为时已晚,因为其photo字段将已使用其新值更新; 您仍然可以从数据库中检索现有记录的副本,并通过它删除旧文件.这是一个示例实现:
class UserProfile(models.Model):
...
def save(self, *args, **kwargs):
# grab a copy of the old record from the database
oldrec = type(self).objects.get(pk=self.pk)
# save the current instance, and keep the result
result = super(UserProfile, self).save(*args, **kwargs)
# if the path is the same, the file is overwritten already
# and no deletion is necessary
if oldrec.photo.path != self.photo.path:
oldrec.photo.delete()
# return the result received from the parent save() method
return result
Run Code Online (Sandbox Code Playgroud)
要为文件选择指定可接受的类型,您需要为将为您的字段呈现accept的<input>标记提供属性; 您需要在自定义表单中覆盖窗口小部件.
| 归档时间: |
|
| 查看次数: |
5764 次 |
| 最近记录: |