How can I upload multiple files to a model field?

后端 未结 3 928
野的像风
野的像风 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:15

    Would suggest using an M2M field from Feed model to FeedFile model. Makes it all the more easier while querying for files of a particular Feed object, which i feel is also the most common usecase for Feed objects

    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.ManyToManyField(FeedFile)
    
    class FeedFile(models.Model):
        file = models.FileField(upload_to="files/%Y/%m/%d")
    
    0 讨论(0)
  • 2020-12-08 12:31

    You have to create a separate model for the files and connect them with a foreign key:

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

    I hope this helps.

    0 讨论(0)
  • 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 <form> 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

    0 讨论(0)
提交回复
热议问题