【问题标题】:How to add image into a post in django如何在 django 中将图像添加到帖子中
【发布时间】:2013-11-01 10:18:59
【问题描述】:

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

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

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

【问题讨论】:

  • 发布博客文章是带有图像字段的单一表单吗?如果是这样,在用户准备好发布表单之前不会上传任何内容,因此您不需要任何临时图像。
  • no 我是在ajax上建博客,用jquery-file-upload上传图片
  • 它像 facebook 状态
  • 当用户开始写草稿时,可以在服务器上创建具有草稿状态的 BlogEntry 对象,当他附加图像时 - 当他发布 blogentry - 条目时,它们会转到与 ForeignKeys 相关的模型仅在丢弃时出现在公共场合 - BlogEntry 对象与相关图像一起从数据库中删除。假设模型图像将对应于博客中的图像。您可以覆盖模型的delete 方法或在post-delete 信号上附加一个信号接收器,并附加将删除与图像存储上的图像对象对应的文件的添加功能。
  • 关于丢弃 - 您只需指定“丢弃条目”的条件。我可以想象两种变体 - 您可以为用户添加特殊功能以“丢弃”草稿博客条目,因此服务器将收到删除 blo 条目的查询。或者您可以跟踪用户会话 - 如果在会话期间,用户没有公开发布他的条目,则该条目被视为丢弃。

标签: django post image-uploading temporary-files


【解决方案1】:

我建议如下:

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

希望对你有帮助。

【讨论】:

    【解决方案2】:

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

    views.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)
    

    delete 方法已被覆盖,在删除入口文件后删除图像文件。

    模板: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 保护可能会出现一些问题,请参阅here。可能需要将 csrf 令牌复制到 ajax 调用中,请参阅here。 jquery-file-upload 的 Ajax done 回调会将上传的图片加载到页面中,替换持有的图片。

    forms.py

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

    urls.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-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多