You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无文章ID时如何为编辑器中的文章上传文档?

解决方案:文章未创建时的文件上传问题

方案1:允许文件先独立上传,后续关联文章

修改DocumentModel的外键字段,允许文件暂时不绑定文章,待文章创建后自动关联。

模型修改

# documentmodels.py
class DocumentModel(models.Model):
    id=models.AutoField(primary_key=True, auto_created=True, verbose_name="DOCUMENT_ID")
    user_fk_doc=models.ForeignKey(User, on_delete=models.CASCADE,  related_name="users_fk_doc")
    # 新增null=True, blank=True,允许外键为空
    article_fk_doc=models.ForeignKey(Article, on_delete=models.CASCADE, related_name="articles_fk_doc", null=True, blank=True)
    document=models.FileField(max_length=350,  validators=[FileExtensionValidator(extensions)], upload_to=uploaded_files)
    filename=models.CharField(max_length=100, blank=True)
    filesize=models.IntegerField(default=0, blank=True)
    mimetype=models.CharField(max_length=100, blank=True)
    created_at=models.DateField(auto_now_add=True)

文章创建时自动绑定未关联文件

在ArticleViewSet中重写创建逻辑,新文章生成后,批量将当前用户未绑定的文件关联到该文章:

# Article views.py
from rest_framework import status

class ArticleViewSet(viewsets.ModelViewSet):
    queryset=Article.objects.all()
    serializer_class=ArticleSerializer
    permission_classes=[permissions.IsAuthenticated]
    authentication_classes = [authentication.TokenAuthentication]

    def create(self, request, *args, **kwargs):
        # 先完成文章创建
        response = super().create(request, *args, **kwargs)
        # 批量更新当前用户未关联文章的文件
        DocumentModel.objects.filter(
            user_fk_doc=request.user,
            article_fk_doc__isnull=True
        ).update(article_fk_doc=response.data['id'])
        return response

补充:建议添加定时任务(如Celery),清理超过7天未关联文章的冗余文件,避免存储浪费。


方案2:先创建草稿文章,再上传文件

利用现有Article模型的isDraft字段,用户进入编辑器时自动生成草稿文章,拿到文章ID后再上传文件,编辑完成后更新草稿状态。

新增草稿创建接口

在ArticleViewSet中添加生成草稿的action:

# Article views.py
from rest_framework.decorators import action

class ArticleViewSet(viewsets.ModelViewSet):
    # ... 原有代码 ...

    @action(detail=False, methods=['post'], url_path='create-draft')
    def create_draft(self, request):
        # 生成默认草稿数据
        draft_data = {
            'headline': '临时草稿',
            'isDraft': True,
            'created_by': request.user.id
        }
        serializer = self.get_serializer(data=draft_data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

前端流程

  1. 用户进入编辑器时,先调用/articles/create-draft/接口获取草稿ID
  2. 上传文件时,将该ID作为article_fk_doc参数传入
  3. 编辑完成后,调用文章更新接口,修改标题、内容等字段,并将isDraft设为False

方案3:临时存储文件,创建文章后再迁移

新增临时文件模型存储未绑定的文件,待文章创建后,将文件迁移到正式目录并关联文章。

新增临时文件模型

# documentmodels.py
class TemporaryDocument(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    document = models.FileField(upload_to='temp_files/')
    filename = models.CharField(max_length=100, blank=True)
    filesize = models.IntegerField(default=0, blank=True)
    mimetype = models.CharField(max_length=100, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

临时上传与迁移逻辑

  1. 新增临时文件上传视图,处理用户上传请求
# document views.py
from rest_framework.views import APIView

class TemporaryDocumentUploadView(APIView):
    permission_classes=[permissions.IsAuthenticated]
    authentication_classes= [authentication.TokenAuthentication]
    parser_classes=[FormParser, MultiPartParser]

    def post(self, request):
        serializer = TemporaryDocumentSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(user=request.user)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
  1. 文章创建时迁移临时文件到正式目录
# Article views.py
import os
from django.core.files.storage import default_storage

class ArticleViewSet(viewsets.ModelViewSet):
    # ... 原有代码 ...

    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        article_id = response.data['id']
        # 处理当前用户的临时文件
        temp_docs = TemporaryDocument.objects.filter(user=request.user)
        for temp_doc in temp_docs:
            # 复制文件到正式存储目录
            new_file_path = default_storage.save(
                f'uploaded_files/{temp_doc.filename}',
                temp_doc.document
            )
            # 创建正式文件记录并关联文章
            DocumentModel.objects.create(
                user_fk_doc=request.user,
                article_fk_doc_id=article_id,
                document=new_file_path,
                filename=temp_doc.filename,
                filesize=temp_doc.filesize,
                mimetype=temp_doc.mimetype
            )
            # 删除临时文件及记录
            temp_doc.document.delete()
            temp_doc.delete()
        return response

内容的提问来源于stack exchange,提问作者Abdullah Roshan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:35:22