Django CreateView允许在点击后退按钮显示表单时重新提交数据
我正在尝试制作一个带有上传图像的应用程序。问题是,我想限制上传图片的可能性,每天只上传一次。除了用户使用浏览器的“后退”按钮外,其他一切都正常工作。他可以向系统发送垃圾邮件。预防这种情况的正确方法是什么 models.pyDjango CreateView允许在点击后退按钮显示表单时重新提交数据,django,django-models,django-forms,django-class-based-views,Django,Django Models,Django Forms,Django Class Based Views,我正在尝试制作一个带有上传图像的应用程序。问题是,我想限制上传图片的可能性,每天只上传一次。除了用户使用浏览器的“后退”按钮外,其他一切都正常工作。他可以向系统发送垃圾邮件。预防这种情况的正确方法是什么 models.py # Admin option to select from PHOTO_STATUS = ( ('ir', 'In Review'), ('ap', 'Approved'), ('tr', 'Trash'), ) def pause(): r
# Admin option to select from
PHOTO_STATUS = (
('ir', 'In Review'),
('ap', 'Approved'),
('tr', 'Trash'),
)
def pause():
return timezone.now() + timezone.timedelta(minutes=5)
# Main photo upload app
class PhotoUpload(models.Model):
'''After the user finishes the challenge
he can upload a photo using this app'''
# The date when a user uploads a photo
date_upload = models.DateTimeField(default=timezone.now)
# The date when user can upload another photo
# pause = date_upload + timezone.timedelta(minutes=20)
pause_upload = models.DateTimeField(default=pause)
# The status of the photo
status = models.CharField(max_length=2, default='ir', choices=PHOTO_STATUS)
# The date when the admin aproves the photo
date_approved = models.DateTimeField(default=timezone.now,
blank=True,
null=True)
# The date when the admin soft-deletes the photo
date_deleted = models.DateTimeField(default=timezone.now,
blank=True,
null=True)
user = models.ForeignKey(User)
# A function that defines the path where the photo
# will be uploaded and that will change the filename.
def path_and_rename(instance, filename):
extension = filename.split('.')[-1]
if User.is_authenticated:
# print(instance._user.username)
return 'uploads/{}-{}.{}'.format(instance.user.username,
instance.date_upload,
extension)
else:
return 'uploads/{}.{}'.format(instance.date_upload, extension)
# Application side file size check
def file_size(value):
limit = 2 * 1024 * 1024
if value.size > limit:
raise ValidationError(
'File too large. Size should not exceed 2 MB.')
image = models.ImageField(upload_to=path_and_rename,
validators=[file_size],
null=True,
blank=True)
def __str__(self):
return str(self.pause_upload)
看法
谢谢大家!
编辑
这是我的模板,我使用了一个名为照片的模板标签和一个名为经过时间的模板过滤器
{% for photo in photos %}
<div class="container vertical-centre">
{% if not photo.pause_upload|elapsed:1 %}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="centre-colour">
{% if photo.user.first_name %}{{ photo.user.first_name }}{% else %}{{ photo.user.username }}{% endif %} you can upload another photo anytime after:<br>
<div id="clockdiv" class="centre-colour">
<span class="hours"></span> Hours <span class="minutes"></span> minutes
<span class="seconds"></span> seconds
</div>
</h1>
</div>
</div>
{% else %}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="centre-colour">
CONGRATULATIONS {% if photo.user.first_name %}{{ photo.user.first_name }}{% else %}{{ photo.user.username }}{% endif %}!!!
</h1>
<h2 class="centre-colour">
Upload photo:
</h2>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
{% crispy form %}
</div>
</form>
<h4 class="centre-colour">or</h4>
<a href="{% url 'home' %}" role="button" id="goHome" class="btn btn-primary btn-block">Start again</a>
</div>
</div>
{% endif %}
</div>
{% endfor %}
{%用于照片中的照片%}
{%如果不是照片。暂停上传|经过时间:1%}
{%if photo.user.first_name%}{{photo.user.first_name}{%else%}{{photo.user.username}{%endif%}之后您可以随时上载另一张照片:
小时分钟
秒
{%else%}
祝贺你{%if photo.user.first_name%}{{photo.user.first_name}}{%else%}{{photo.user.username}}{%endif%}!!!
上传照片:
{%csrf_令牌%}
{%crispy form%}
或
{%endif%}
{%endfor%}
这里是模板标签和过滤器
register = template.Library()
@register.inclusion_tag('photos/photos_tags.html')
def photos_up(request, number=1):
a = PhotoUpload.objects.filter(user__username=request).exists()
if a:
return {'form': PhotoUploadForm(),
'photos': PhotoUpload.objects.filter(
user__username=request
).order_by(
'-pause_upload')[:number]
}
else:
return {'form': PhotoUploadForm(),
'photos': PhotoUpload.objects.all()[:number]
}
register = template.Library()
@register.filter(expects_localtime=True)
def elapsed(time, seconds):
return time + timezone.timedelta(seconds=seconds) < timezone.now()
register=template.Library()
@register.inclusion\u标记('photos/photos\u tags.html'))
def照片上传(请求,编号=1):
a=PhotoUpload.objects.filter(用户\用户名=请求).exists()
如果是:
返回{'form':PhotoUploadForm(),
“照片”:PhotoUpload.objects.filter(
用户\用户名=请求
).订购(
“-暂停上传”[:编号]
}
其他:
返回{'form':PhotoUploadForm(),
“照片”:PhotoUpload.objects.all()[:number]
}
register=template.Library()
@register.filter(预期\u localtime=True)
已用def(时间,秒):
返回时间+时区.timedelta(秒=秒)
除非用户决定从成功页面点击后退按钮,否则一切都正常工作。然后,上传页面将再次进入表单视图,而不是进入计数器。您可以在数据库中添加一个属性,名为
lastuploaded(DateTimeField)
,当用户上传照片时,检查lastuploaded
是否比当前时间早一天。
编辑:
将lastuploaded字段添加到模型中
class PhotoUpload(models.Model):
last_uploaded = models.DateTimeField(null=True, blank=True, default=timezone.now)
现在在视图的form_有效函数中进行检查
def form_valid(self, form):
photo_upload_object = PhotoUpload.objects.filter(user=self.request.user).latest('last_uploaded')
if photo_upload_object.last_uploaded + datetime.datetime.timedelta(days=1) < current_time and photo_upload_object.last_uploaded is not None:
form.instance.user = self.request.user
return super(PhotoUploadCreate, self).form_valid(form)
else:
return HttpResponse("some error")
def form_有效(self,form):
photo\u upload\u object=PhotoUpload.objects.filter(user=self.request.user).latest('last\u upload'))
如果photo_upload_object.last_upload+datetime.datetime.timedelta(天=1)<当前时间和photo_upload_object.last_upload不是无:
form.instance.user=self.request.user
返回super(PhotoUploadCreate,self)。form_有效(form)
其他:
返回HttpResponse(“某些错误”)
其他方法可能是保存上次上传的cookie,但在所有情况下都不适用,比如从不同的设备登录。
如果时间增量(当前时间)小于一天,则可以保存上次上传的图像的时间戳并禁用上传。这里有一个可能的插件@utkbansal谢谢你的评论。请查看我的更新。为什么要使用模板标记进行此操作。当用户的上传请求到达您的服务器时,检查当前时间>UserObject.lastuploaded+1天
(伪代码)。并且不要为此在模板中添加任何datetime字段。这将是多余的。我是一个初学者,我发现在模板标记中创建逻辑比在CreateView中更容易。我知道这不尊重干燥的概念,但这是唯一有效的方法。和正在工作,除非用户点击后退按钮。在部署之前,我将进行代码重构。上述解决方案是纯后端解决方案,用户可以做任何他想做的事情,但如果他上传了一张照片,那么他只能在一天后上传。不要使用模板标签,这只会让初学者的事情变得复杂。你能告诉我把代码放在哪里以及如何放吗?上面的编辑会给你一个方法的要点
def form_valid(self, form):
photo_upload_object = PhotoUpload.objects.filter(user=self.request.user).latest('last_uploaded')
if photo_upload_object.last_uploaded + datetime.datetime.timedelta(days=1) < current_time and photo_upload_object.last_uploaded is not None:
form.instance.user = self.request.user
return super(PhotoUploadCreate, self).form_valid(form)
else:
return HttpResponse("some error")