5

我正在构建一个博客系统,允许用户将图像添加到他们的博客。

当用户添加图片时,图片会自动上传,这是在发布博客之前发生的,那么我应该如何处理上传的图片,这些图片有点像临时图片,因为如果用户发布博客,这些图片就会有该博客的外键,并保存到某个文件夹中,但如果用户丢弃该博客,则应删除这些临时图像。

问题是如何获取第一个上传的图片,当博客实际发布时?我应该在哪里存储这些临时图像?以及如何判断用户是否丢弃了博客?

4

2 回答 2

5

我建议如下:

  1. 修改 Post 模型以添加一个名为published的日期时间字段,该字段允许 NULL。
  2. 使用已发布字段来确定帖子是否已发布。如果发布的字段为 NULL,则帖子将被视为草稿,否则将被视为发布。
  3. 点击创建帖子按钮后立即创建帖子。这将为您提供一个带有id的 Post 对象,您可以将其绑定到 ModelForm 并显示给用户进行编辑。因此,当他们添加图片时,您可以将其上传并以您想要的任何方式将其绑定到帖子的id
  4. 仅当您点击发布按钮时,才将发布的内容更改为 datetime.now()。
  5. 删除已发布或草稿帖子应删除所有链接资源,如图像。

希望能帮助到你。

于 2013-10-29T05:43:53.137 回答
3

您是否使用该django.contrib.auth模块来登录和注销用户?这有一个将当前User对象附加到request参数的中间件组件,并且可以很好地与 Ajax 配合使用。如果用户当前未登录,它还提供登录页面的重定向。更多信息在这里。一个可能的解决方案:

视图.py:

from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.utils import simplejson
from django.contrib.auth.decorators import login_required
from filetransfers.api import prepare_upload, serve_file
from blog.models import BlogEntry
from blog.forms import BlogEntryForm

@login_required
def createBlogEntry(request):
    return render_to_response('blogEdit.html', { 'form' : BlogEntryForm() })

@login_required
def uploadImage(request):
  if request.method == 'POST':
     form = BlogEntryForm(request.POST, request.FILES)
     if form.is_valid():
        newEntry = BlogEntry()
        newEntry = request.FILES['blogImage']
        newEntry.image = request.FILES['file'].name
        newEntry.user = request.user

        # delete unsaved previous blog post
        try:
            oldEntry = BlogEntry.objects.get(user=request.user,completed=False)
            oldEntry.delete()
        except:
            pass

        newEntry.save()
        return HttpResponse(simplejson.dumps({'imageLocation' : '/static/media/blogImgs/%s' % request.FILES['image'].name }), mimetype='application/javascript')
  return HttpResponse(simplejson.dumps({"error" : 101, "message" : "Big error!"}}), mimetype="application/json")

@login_required
def uploadText(request):
if request.method == 'POST':
    if form.is_valid():
        newEntry = BlogEntry()
        try:
            newEntry = BlogEntry.objects.get(user=request.user,completed=False)
        except:
            pass

        newEntry.blogText = request.POST['blogText']
                    newEntry.completed = True
        newEntry.save()
        return HttpResponse(simplejson.dumps({'result' : 'success'});
  return HttpResponse(simplejson.dumps({"error" : 102, "message" : "other Big error!"}}), mimetype="application/json")

第一种方法将显示页面和表单以创建博客条目,其他方法处理 2 个 ajax 调用以上传图像和文本。图像上传后临时BlogEntry存储,如果之前的条目尚未完成,则现在将其删除。上传文本后,临时博客条目完成并保存。

可能有多个临时博客条目(对于浏览器中的多个选项卡 - 就像这个站点),可能设置了最大数量的项目。如果django.auth.contrib包没有被使用,应该可以使用会话中间件来代替——这里有很多选项。

其余文件的草图:
models.py:

from django.db import models
from django.contrib.auth.models import User

class blogEntry(models.Model):
    user = models.ForeignKey(User)
    created = models.DateField(auto_now_add = True)
    completed = models.BooleanField(default = False)

    blogText = models.TextField()
    image = models.ImageField(upload_to = 'blogImgs/')

    def delete(self, *args, **kwargs):
        # Delete image file also
        storage, path = self.image.storage, self.image.path
        super(ImageModel, self).delete(*args, **kwargs)
        storage.delete(path)

在删除条目文件后,删除方法已被覆盖以删除图像文件。

模板:blogEdit.html

<html><head><title>New Blog Entry</title></head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.fileupload/8.9.0/js/jquery.fileupload.js"></script>
<style type="text/css">
form { float: left; }
#textForm {
width: 320px;
padding: 8px;
}
#textForm textarea {
width: 320px;
height: 150px;
margin-bottom: 8px;
}
#imageForm {
width: 100px;
padding-top: 8px;
}
#blogImage {
width: 120px;
height: 120px;
}
#imageForm input[type=file] {
margin: 8px 0 8px 0;
}
</style>
</head>
<body>
<form id="textForm">{% csrf_token %}
<textarea id="blogText" name="blogText"></textarea>
<input type="button" value="upload text" id="textUpload"/>
<img id="blogImage" src="/static/imgs/holdingImage.png" />
    <input id="fileupload" type="file" name="blogImage">
</form>
<script>
$(function () {
  $('#fileupload').fileupload({
    url: '/ajax/uploadImage/',
    dataType: 'json',
    done: function (e, data) {
        blogImage.attr('src', data.result.imageLocation)
    }
  });
});

$('#textUpload').click(function() {
    $.ajax({
      url: '/ajax/uploadText/',
      dataType: 'json',
      data: $('#blogText').val(),
      done: function(e, data) {
        if(data.result == 'success') {
            // display message / redraw edit area with complete blog, etc..
        } else if(data.error) {
            // error handing code
        }
      }
    });
 });
</script>
</body>
</html>

这使用 jquery-file-upload 上传文件。

使用 Ajax 和 Django csrf 保护可能会出现一些问题,请参见此处。可能需要将 csrf 令牌复制到 ajax 调用中,请参见此处。jquery-file-upload 的 Ajax done 回调会将上传的图像加载到页面中,替换持有的图像。

表格.py

from django import forms

class BlogEntryForm(forms.Form):
  blogImage = forms.FileField()
  blogText = forms.TextField()

网址.py

from django.conf.urls import patterns, include, url
import blog.views

urlpatterns = patterns('',
  url(r'^createEntry/$', 'blog.views.createBlogEntry', name='createBlogEntry'),
  url(r'^ajax/uploadImage/', 'blog.views.uploadImage'),
  url(r'^ajax/uploadText/', 'blog.views.uploadText'),
  ...additional urls for django.contrib.auth
);
于 2013-10-31T12:42:39.533 回答