我怎样才能多文件上传到模型字段?

问题描述 投票:7回答:3

我想通过一个向的ModelForm上传多个文件,所有文件被分配到Model.I的file场通过文档已经走了,我看到它的一个例子,我已经在这里实现,但我只能让我的形式接多个文件,但只有一个得到保存和分配给filesfield.Below是我的代码

models.朋友

class Feed(models.Model):
    user=models.ForeignKey(User,on_delete=models.CASCADE,related_name='feeds')
    text=models.TextField(blank=False,max_length=500)
    files = models.FileField(upload_to="files/%Y/%m/%d")

forms.朋友

class FeedForm(ModelForm):
    class Meta:
        model=Feed
        fields=('text','auth','files')
        widgets={"files":forms.FileInput(attrs={'id':'files','required':True,'multiple':True})}

和views.py

def post_feed(request):
    form_class = FeedForm
    if request.method == 'POST':
        form = form_class(request.POST,request.FILES)
        if form.is_valid():
            feed = form.save(commit=False)
            feed.user = User.objects.get(pk=1)
            feed.pub_date=timezone.now()
            #instance = Feed(files=request.FILES['files'])
           # feed.files=request.FILES['files']
            feed.save()
            return redirect('home')
    else:
        form = form_class()
        return render(request, 'post_feed.html', {'form': form,})

from django.views.generic.edit import FormView
from .forms import FeedForm

class FileFieldView(FormView):
    form_class=FeedForm
    template_name='post_feed.html'
 '''success_url=???   #I dont know what to write here.I thought of putting this
render(request, 'post_feed.html', {'form': form,}) because I just want 
to reload the page but it gave an error,so I removed it entirely.'''

    def post_feed(self,request,*args,**kwargs):
        form_class=self.get_form_class()
        form=self.get_form(form_class)
        filez=request.FILES.getlist('files')
        if form.is_valid():
            for f in filez:
                f.save()
            return self.form_valid(form)     
        else:
            return self.form_invalid(form) 

请帮助我,在此先感谢。

django
3个回答
10
投票

你必须为这些文件创建一个独立的模型,并将它们与外键连接:

class Feed(models.Model):
    user=models.ForeignKey(User, on_delete=models.CASCADE, related_name='feeds')
    text=models.TextField(blank=False, max_length=500)


class FeedFile(models.Model):
    file = models.FileField(upload_to="files/%Y/%m/%d")
    feed = models.ForeignKey(Feed, on_delete=models.CASCADE, related_name='files')

我希望这有帮助。


3
投票

唷,我花了一整天的时间来弄清楚这一点。我的目标是将多个文件分配到一个类的一个实例,就像一个博客实例可以有多个图像。首先第一件事情,你不能用模型(例如博客类中)内的一个models.FileField做到这一点,是因为这个领域并不是用来保存多个文件。因此,解决办法是创建文件单独的模型,并将其与一一对多的关系(外键)连接,因为它是由@Carlos Mermingas回答。够的话,这里是上述情况的代码:

# models.py
class Feed(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE)
text=models.TextField(blank=False, max_length=500)

class FeedFile(models.Model):
file = models.FileField(upload_to="files/%Y/%m/%d")
feed = models.ForeignKey(Feed, on_delete=models.CASCADE)

# forms.py
...
from django.forms import ClearableFileInput
...
class FeedModelForm(forms.ModelForm):
    class Meta:
        model = Feed
        fields = ['text']

class FileModelForm(forms.ModelForm):
    class Meta:
        model = FeedFile
        fields = ['file']
        widgets = {
            'file': ClearableFileInput(attrs={'multiple': True}),
        }
        # widget is important to upload multiple files

# views.py
from .models import FeedFile
...
def create_to_feed(request):
    user = request.user
    if request.method == 'POST':
        form = FeedModelForm(request.POST)
        file_form = FileModelForm(request.POST, request.FILES)
        files = request.FILES.getlist('file') #field name in model
        if form.is_valid() and file_form.is_valid():
            feed_instance = form.save(commit=False)
            feed_instance.user = user
            feed_instance.save()
            for f in files:
                file_instance = FeedFile(file=f, feed=feed_instance)
                file_instance.save()
    else:
        form = FeedModelForm()
        file_form = FileModelForm()

    # the rest is the basic code: template_name, context, render etc. 

# in your template.html <form> tag must include enctype="multipart/form-data"

除此之外,如果你想看到在管理面板上传的文件,你可以使用InlineModelAdmin对象。下面是代码:

# admin.py of your app
from django.contrib import admin
from .models import Feed, FeedFile

class FeedFileInline(admin.TabularInline):
    model = FeedFile


class FeedAdmin(admin.ModelAdmin):
    inlines = [
        FeedFileInline,
    ]

admin.site.register(Feed, FeedAdmin)

有关qazxsw POI,qazxsw POI的详细信息,如何将qazxsw POI


0
投票

建议使用从file upload模型的M2M领域Model Forms模型。使这一切更在查询特定widget in Model Form对象的文件,这我觉得也是Feed对象最常见的用例更容易

FeedFile
© www.soinside.com 2019 - 2024. All rights reserved.