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

Django多对多字段报错:不存在root_post_Picture表

相关代码

models.py

class Pictures(models.Model):
    Post_id=models.IntegerField()
    Post_type=models.CharField(max_length=15)
    Picture = models.ImageField(upload_to="images/posts")
class Files(models.Model):
    Post_id = models.IntegerField()
    Post_type = models.CharField(max_length=15)
    File = models.FileField(upload_to="documents/posts",validators=[documentvalidator])
class Videos(models.Model):
    Post_id = models.IntegerField()
    Post_type = models.CharField(max_length=15)
    Video = models.FileField(upload_to="videos/posts",validators=[videovalidator])
class Post(models.Model):
    post = models.CharField(max_length=900)
    Date = models.DateTimeField(default=django.utils.timezone.now)
    Picture=models.ManyToManyField(Pictures, blank=True)
    File = models.ManyToManyField(Files, blank=True)
    Video = models.ManyToManyField(Videos, blank=True)
    likes=models.IntegerField(default=0)
    dislikes = models.IntegerField(default=0)
    coments = models.IntegerField(default=0)

views.py

def postcreation(request):
    Videoarray=[]
    Picturearray=[]
    Filearray=[]
    form=AbsolutePostForm(request.GET)
    file = Fileform(request.FILES)
    pic = PictureForm(request.FILES)
    vid = VideoForm(request.FILES)
    if request.method=="POST":
        file = Fileform(request.FILES)
        if "File" in request.POST:
            if file.is_valid():
                File=Files(Post_type="posts",Post_id=get_id_generation("postids.txt"),File=request.FILES["File"])
                File.save()
                Filearray.append(File)
                print("file")
                return HttpResponse("file")
        pic = PictureForm(request.FILES)
        if "Picture" in request.FILES:
            if pic.is_valid():
                Picture = Pictures(Post_type="posts", Post_id=get_id_generation("postids.txt"),Picture=request.FILES["Picture"])
                Picture.save()
                Picturearray.append(Picture)
                print("pic")
                return HttpResponse("picture")
        vid = VideoForm(request.FILES)
        if "Video" in request.FILES:
            if vid.is_valid():
                Video = Videos(Post_type="posts", Post_id=get_id_generation("postids.txt"),Video=request.FILES["Video"])
                Video.save()
                print("vid")
                Videoarray.append(Video)
        if "Postcoment" in request.POST:
            form = AbsolutePostForm(request.POST)
            if form.is_valid():
                post=form.cleaned_data["Postcoment"]
                Main=Post(post=post)
                Main.save()
                for obj in Filearray:
                    Main.File.add(obj)
                for obj in Videoarray:
                    Main.File.add(obj)
                for obj in Picturearray:
                    Main.File.add(obj)
                return HttpResponse("welldone")
    context={"form":form,"pic": pic,"file":file,"vid":vid}
    return render(request,"postcreationpage.html",context)

forms.py

class AbsolutePostForm(forms.Form):
    Postcoment=forms.CharField(label="",required=False,max_length=700, widget=(forms.Textarea(attrs={"required": "True",'rows':"30", 'cols':"60", 'class':"postgrid", 'placeholder':"DECRIVEZ VOTRE POSTE"})))
class Fileform(forms.Form):
    File = forms.FileField(label="",required=False,widget=(forms.FileInput(attrs={"class":"invisible"})), validators=[documentvalidator])
class PictureForm(forms.Form):
    Picture = forms.ImageField(label="",required=False,widget=(forms.FileInput(attrs={"class":"invisible"})))
class VideoForm(forms.Form):
    Video = forms.FileField(label="",required=False,widget=(forms.FileInput(attrs={"class":"invisible"})),validators=[videovalidator])

模板代码

<div class="panel">
            <div class="seperate">
                <div class="attachements">
                    <div style="position: relative;">
                        <div style="width:40px; 
                                    height: 35px; ">
                                        <form action="" method="POST" enctype="multipart/form-data">
                                            {% csrf_token %}
                                            {{ pic }}
                                            <button type="submit" class="submiters">sauvegarder l'image choisie</button>
                                        </form>
                                    </div>
                        <img src="{% static 'im.png' %}" class="pinner">
                    </div>
                    <div style="position: relative;">
                        <div style="
                                    width:40px; 
                                    height: 35px; ">
                                        <form action="" method="POST" enctype="multipart/form-data">
                                            {% csrf_token %}
                                            {{ vid }}
                                            <button type="submit" class="submiters" style="top: 100px;">sauvegarder la video choisie</button>
                                        </form>
                                    </div>
                        <img src="{% static 'vid.png' %}" class="pinner">
                    </div>
                    <div style="position: relative;">
                        <div style="
                                    width:40px; 
                                    height: 35px; ">
                                    <form action="" method="POST" enctype="multipart/form-data">
                                        {% csrf_token %}
                                        {{ file }}
                                        <button type="submit" class="submiters" style="top: 150px;">sauvegarder le document choisi</button>
                                    </form>
                                </div>
                        <img src="{% static 'doc.png' %}" class="pinner">
                    </div>
                </div>
                <div>
                    <form action="" method="POST" enctype="multipart/form-data">
                        {% csrf_token %}
                        {{ form }}
                        <br>
                        <br>
                        <button type="submit">POSTER</button>
                    </form>
                </div>
            </div>

问题原因

  1. 模型关联逻辑重复:你同时用了两种方式关联Post和媒体模型:一是在Pictures/Files/Videos里加Post_id手动关联,二是在Post里用ManyToManyField自动关联。这会让Django ORM混乱,导致多对多的中间表没有被正确生成。

  2. 视图代码错误:在关联媒体到Post时,你把Video和Picture都错误地加到了Main.File字段里,这不仅逻辑错误,还会让ORM的关联操作异常。

  3. 迁移文件未正确生成:因为模型逻辑冲突,第一次生成的迁移文件可能没有包含多对多中间表的创建语句,导致数据库里没有root_post_Picture这张表。


解决方案

1. 修正模型设计,移除手动关联字段

删掉Pictures/Files/Videos中的Post_id和Post_type,让多对多字段自动维护关联:

# 修改后的models.py
class Pictures(models.Model):
    Picture = models.ImageField(upload_to="images/posts")

class Files(models.Model):
    File = models.FileField(upload_to="documents/posts", validators=[documentvalidator])

class Videos(models.Model):
    Video = models.FileField(upload_to="videos/posts", validators=[videovalidator])

class Post(models.Model):
    post = models.CharField(max_length=900)
    Date = models.DateTimeField(default=django.utils.timezone.now)
    Picture = models.ManyToManyField(Pictures, blank=True)
    File = models.ManyToManyField(Files, blank=True)
    Video = models.ManyToManyField(Videos, blank=True)
    likes = models.IntegerField(default=0)
    dislikes = models.IntegerField(default=0)
    coments = models.IntegerField(default=0)

2. 重新生成并执行迁移

# 删除旧的初始迁移文件(如果之前的迁移已经执行过,注意备份数据)
rm root/migrations/0001_initial.py

# 生成新的迁移文件
python manage.py makemigrations

# 同步数据库
python manage.py migrate

3. 修正视图中的关联错误

把错误的关联代码改成对应字段:

# 修改views.py中的这段代码
if form.is_valid():
    post = form.cleaned_data["Postcoment"]
    Main = Post(post=post)
    Main.save()
    for obj in Filearray:
        Main.File.add(obj)
    for obj in Videoarray:
        Main.Video.add(obj)  # 这里改成Video字段
    for obj in Picturearray:
        Main.Picture.add(obj)  # 这里改成Picture字段
    return HttpResponse("welldone")

4. 修复表单提交的无状态问题(重要)

当前视图中,每次上传媒体后都会返回HttpResponse,导致Filearray/Picturearray/Videoarray里的数据会丢失(HTTP请求是无状态的)。建议用session临时存储已上传的媒体ID:

比如,保存图片时把ID存入session:

# 保存Picture的代码修改
if pic.is_valid():
    Picture = Pictures(Picture=request.FILES["Picture"])
    Picture.save()
    # 存入session
    request.session['picture_ids'] = request.session.get('picture_ids', []) + [Picture.id]
    print("pic")
    return HttpResponse("picture")

提交Post时再从session取出并关联:

# 提交Post的代码修改
if form.is_valid():
    post = form.cleaned_data["Postcoment"]
    Main = Post(post=post)
    Main.save()
    # 关联文件
    file_ids = request.session.get('file_ids', [])
    for fid in file_ids:
        f = Files.objects.get(id=fid)
        Main.File.add(f)
    # 关联视频
    video_ids = request.session.get('video_ids', [])
    for vid in video_ids:
        v = Videos.objects.get(id=vid)
        Main.Video.add(v)
    # 关联图片
    picture_ids = request.session.get('picture_ids', [])
    for pid in picture_ids:
        p = Pictures.objects.get(id=pid)
        Main.Picture.add(p)
    # 清空session
    del request.session['file_ids']
    del request.session['video_ids']
    del request.session['picture_ids']
    return HttpResponse("welldone")

内容的提问来源于stack exchange,提问作者Lord vic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 05:17:32