How can I upload multiple files to a model field?

后端 未结 3 927
野的像风
野的像风 2020-12-08 12:05

I want to upload multiple files through a ModelForm,with all files to be assigned to a file field of the Model.I have gone through the docs and I saw an example

3条回答
  •  醉梦人生
    2020-12-08 12:34

    Phew, it took me a whole day to figure out this. My goal was to assign multiple files to one instance of a class, like a Blog instance can have multiple Images. First things first, you cannot do this with one models.FileField inside a model (for example inside Blog class), because this field was not designed to save multiple files. So the solution is to create separate model for the files and connect them with One-to-Many Relationship (Foreign Key) as it was answered by @Carlos Mermingas. Enough words, here is the code for the above situation:

    # 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 
    tag must include enctype="multipart/form-data"

    Bonus: if you want to see uploaded files in admin panel, you can use InlineModelAdmin objects. Here is the code:

    # 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)
    

    For the more details on file upload, Model Forms, how to include widget in Model Form

提交回复
热议问题