在 Django 中保存多个图像的问题

Problems with save several images in Django

我在 Django 中保存文件时遇到问题。请问有人可以帮助我吗?

我有包含 2 个字段的表单:descriptionimage。通过图像字段,用户可以加载多个图像。为了创建图像字段,我使用了 django-multiupload 应用程序。我还通过 ajax 将数据加载到服务器。我尝试了下一个代码,但它出现了错误。如何解决这个问题?保存图像文件的问题。从 Traceback 我了解到问题是从这条观点开始的:article = article_form.save(commit=False)

models.py:

class Article(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    description = models.TextField(_('Description'))

class Image(models.Model):
    article= models.ForeignKey(Article, on_delete=models.CASCADE)
    image = models.FileField(_('Image'), upload_to='images/%Y/%m/%d/')

forms.py:

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ('description', )

    image = MultiFileField()

    def save(self, commit=True):
        instance = super(ArticleForm, self).save(commit)
        for each in self.cleaned_data['image']:
            Image.objects.create(image=each, article=instance)
        return instance

views.py:

def article_add(request, project_id):
    data = dict()
    project = get_object_or_404(Project, pk=project_id)
    if request.method == 'POST':
        article_form = ArticleForm(request.POST, request.FILES)
        if article_form.is_valid():
            article = article_form.save(commit=False)
            article.project = project 
            article.save()
            data['form_is_valid'] = True
            articles = Article.objects.all
            context = {'articles': articles}
            context.update(csrf(request))
            data['html_article'] = render_to_string('project/article_list.html', context)
        else:
            data['form_is_valid'] = False
    else:
        article_form = ArticleForm()
    context = {'article_form': article_form}
    data['html_article_form'] = render_to_string('project/article_add.html', context, request=request)
    return JsonResponse(data)

JS:

$(function () {
    var loadForm = function () {
        var btn = $(this);
        $.ajax({
            url: btn.attr("data-url"),
            type: 'get',
            dataType: 'json',
            beforeSend: function () {
                $("#modal").modal("show");
            },
            success: function (data) {
                $("#modal .modal-content").html(data.html_article_form);
            }
        });
    };

    var saveForm = function () {
        var form = $(this);
        var dataForm = new FormData(form.get(0));
        $.ajax({
            url: form.attr("action"),
            data: dataForm 
            type: form.attr("method"),
            dataType: 'json',
            success: function (data) {
                if (data.form_is_valid) {
                    $("#article-list").html(data.html_article);
                    $("#modal").modal("hide");
                }
                else {
                    $("#modal .modal-content").html(data.html_article_form);
                }
            }
        });
        return false;
    };

    // Create Article
    $("#article-add-button").click(loadForm);
    $("#modal").on("submit", ".js-article-add-form", saveForm);

    // Update Article
    $("#article-list").on("click", "#js-edit-article-button", loadForm);
    $("#modal").on("submit", ".js-article-edit-form", saveForm);
});

错误:

Traceback (most recent call last):
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\reversion\revisions.py", line 296, in do_revision_context
    return func(*args, **kwargs)
  File "C:\Users\Nurzhan\PycharmProjects\RMS\project\views.py", line 1673, in article_add
    article = article_form.save(commit=False)
  File "C:\Users\Nurzhan\PycharmProjects\RMS\project\forms.py", line 271, in save
    Image.objects.create(image=each, article=instance)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py", line 399, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py", line 1045, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Nurzhan\AppData\Local\Programs\Python\Python35-32\lib\site-packages\sql_server\pyodbc\base.py", line 539, in execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: ('23000', '[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]�������� ���������� INSERT � ������������ FOREIGN KEY "project_image_article_id_1cd62783_fk_project_article_id". �������� ��������� � ���� ������ "RMS", ������� "dbo.project_article", column \'code\'. (547) (SQLExecDirectW)')

这是一个完整性错误,表明外键不存在。源于这段代码

def save(self, commit=True):
    instance = super(ArticleForm, self).save(commit)
    for each in self.cleaned_data['image']:
        Image.objects.create(image=each, article=instance)
    return instance

第一次调用表单保存方法时,文章没有保存。也就是说这篇文章没有PK。这反过来意味着图像不遵守其外键的引用完整性规则。

我建议您将此位移动到您的视图中,它可能看起来像这样。

if article_form.is_valid(): 
        article = article_form.save(commit=False)
        article.project = project 
        article.save()
        for each in article_form.cleaned_data['image']:
            Image.objects.create(image=each, article=instance)

在文章提交后执行。