Django CreateView 允许在点击后退按钮时显示表单时重新提交数据
Django CreateView allows resubmission of the data when the form is displayed when hiting the back button
我正在尝试制作一个带有上传图片的应用。问题是我想将上传图像的可能性限制为每天一次。一切正常,除非用户使用浏览器的后退按钮。他可以向系统发送垃圾邮件。防止这种情况的正确方法是什么?
models.py
# 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)
查看
class PhotoUploadCreate(CreateView):
model = PhotoUpload
template_name = 'upload_photo.html'
form_class = PhotoUploadForm
def form_valid(self, form):
form.instance.user = self.request.user
return super(PhotoUploadCreate, self).form_valid(form)
def get_success_url(self):
return reverse('success')
谢谢!
编辑
这是我的模板,我在其中使用了一个名为 photos 的模板标签和一个名为 elapsed.
的模板过滤器
{% 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 %}
这里是模板标签和过滤器
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()
除非用户决定从 成功 页面点击后退按钮,否则一切正常。然后 上传 页面将再次进入表单视图,而不是转到柜台。
您可以将属性作为 lastuploaded (DateTimeField)
放入数据库中,当用户上传照片时检查 lastuploaded
是否比当前时间早一天。
编辑:
将 lastuploaded 字段添加到您的模型。
class PhotoUpload(models.Model):
last_uploaded = models.DateTimeField(null=True, blank=True, default=timezone.now)
现在在您视图的 form_valid 函数中进行检查。
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")
其他方法可能是将上次上传的内容保存在 cookie 中,但这并不适用于所有情况,例如从不同设备登录。
我正在尝试制作一个带有上传图片的应用。问题是我想将上传图像的可能性限制为每天一次。一切正常,除非用户使用浏览器的后退按钮。他可以向系统发送垃圾邮件。防止这种情况的正确方法是什么?
models.py
# 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)
查看
class PhotoUploadCreate(CreateView):
model = PhotoUpload
template_name = 'upload_photo.html'
form_class = PhotoUploadForm
def form_valid(self, form):
form.instance.user = self.request.user
return super(PhotoUploadCreate, self).form_valid(form)
def get_success_url(self):
return reverse('success')
谢谢!
编辑 这是我的模板,我在其中使用了一个名为 photos 的模板标签和一个名为 elapsed.
的模板过滤器{% 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 %}
这里是模板标签和过滤器
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()
除非用户决定从 成功 页面点击后退按钮,否则一切正常。然后 上传 页面将再次进入表单视图,而不是转到柜台。
您可以将属性作为 lastuploaded (DateTimeField)
放入数据库中,当用户上传照片时检查 lastuploaded
是否比当前时间早一天。
编辑:
将 lastuploaded 字段添加到您的模型。
class PhotoUpload(models.Model):
last_uploaded = models.DateTimeField(null=True, blank=True, default=timezone.now)
现在在您视图的 form_valid 函数中进行检查。
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")
其他方法可能是将上次上传的内容保存在 cookie 中,但这并不适用于所有情况,例如从不同设备登录。