Как добавить изображение в пост в django

Я создаю систему блогов, которая позволяет пользователям добавлять изображения в свой блог.

Когда пользователь добавляет изображение, оно будет загружено автоматически, это произошло до того, как блог был опубликован, поэтому, как я должен обрабатывать загруженное изображение, это как временное изображение, потому что если пользователь публикует блог, эти изображения будут иметь внешний ключ к этому блогу, и сохраненный в некоторой папке, но если пользователь отклоняет блог, эти временные изображения должны быть удалены.

проблема в том, как получить первые загруженные изображения, когда блог действительно размещен? где я должен хранить эти временные изображения? и как я могу сказать, если пользователь отказывается от блога?

2 ответа

Решение

Я бы предложил следующее:

  1. Измените модель Post, чтобы добавить поле даты и времени, называемое опубликованным, что позволяет использовать NULL.
  2. Используйте поле опубликовано, чтобы определить, опубликовано сообщение еще или нет. Сообщение будет считаться черновиком, если опубликованное поле имеет значение NULL, в противном случае будет опубликовано.
  3. Создайте сообщение, как только вы нажмете кнопку "Создать сообщение". Это даст вам объект Post с идентификатором, который вы можете привязать к ModelForm и отобразить пользователю для редактирования. Поэтому, когда они добавляют изображение, вы можете загрузить его и связать с идентификатором сообщения любым удобным для вас способом.
  4. Измените опубликованное на datetime.now(), только когда вы нажмете кнопку публикации.
  5. Удаление опубликованного или черновика сообщения должно удалить все связанные ресурсы, такие как изображения.

Надеюсь, поможет.

Вы используете django.contrib.auth модуль для входа и выхода пользователей? Это компонент промежуточного программного обеспечения, который добавляет текущий User возражать против request параметр и работает достаточно хорошо с Ajax. Он также предоставляет перенаправления для входа на страницы, если пользователь не вошел в систему. Подробнее здесь. Возможное решение:

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 см. Здесь. Может потребоваться скопировать токен csrf в вызов ajax, см. Здесь. Ajax done callback для jquery-file-upload загрузит загруженное изображение на страницу, заменив удерживающее изображение.

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
);
Другие вопросы по тегам