Chive / django-multiupload

Dead simple drop-in multi file upload field for Django forms using HTML5's multiple attribute.
MIT License
279 stars 81 forks source link

Using it with ForeignKey #4

Closed dfrojas closed 9 years ago

dfrojas commented 9 years ago

Im trying to use django-multiupload but with a ForeignKey:

class Bulk(models.Model):
    school = models.ForeignKey(School)
    file = models.FileField(upload_to='attachments')

    def __unicode__(self):
        return self.school.name

And this in the forms:

class MyUploadForm(ModelForm):
    fotos = MultiFileField(max_num=3, min_num=1, max_file_size=1024*1024*5)

    class Meta():
        model = Bulk  
        exclude = ['file'] 

    def save(self, commit=True):
        super(MyUploadForm, self).save(commit=commit)

        for each in self.cleaned_data['fotos']:
            att = Bulk(colegio=self.instance, file=each)
            att.save()

       return self.instance

But im getting_ Cannot assign "'ICIT'": "Bulk.school" must be a "School" instance.

How can i use this with a foreignkey because if i use the school field with charfield works fine.

Chive commented 9 years ago

Hello there, I'll look into it as soon as I am home from my military service in about a month. Sorry for the delay!

Chive commented 9 years ago

Hello @dfrojas. I set up your code in my environment and was able to reproduce your issue.

The problem is that you're trying to link Bulk with itself, since you're in a ModelForm for the model Bulk and also assing Bulk(colegio=self.instance), where self.instance is actually a Bulk object. So you should rather have your ModelForm for the model School or Colegio.

Full code

forms.py

from django.forms import ModelForm

from multiupload.fields import MultiFileField

from .models import Bulk, School

class MyUploadForm(ModelForm):
    fotos = MultiFileField(max_num=3, min_num=1, max_file_size=1024*1024*5)

    class Meta():
        model = School
        exclude = ['file']

    def save(self, commit=True):
        super(MyUploadForm, self).save(commit=commit)

        for each in self.cleaned_data['fotos']:
            att = Bulk(school=self.instance, file=each)
            att.save()

        return self.instance

models.py

from django.db import models
from django.utils.translation import ugettext_lazy as _

class School(models.Model):
    name = models.CharField(_('Name'), max_length=255)

class Bulk(models.Model):
    school = models.ForeignKey(School)
    file = models.FileField(upload_to='attachments')

    def __unicode__(self):
        return self.school.name

views.py

from django.views.generic.edit import FormView, CreateView

from .forms import MyUploadForm
from .models import Bulk

class MyUploadView(CreateView):
    model = Bulk
    form_class = MyUploadForm
    template_name = 'form.html'
    success_url = '?success'

Hope I could solve your issue. Feel free to reopen if you're still having issues.

marojenka commented 9 years ago

Hi, is there a simple way to use this approach with save(commit=False)? It must be pretty common situation. All I can think of is moving

        for each in self.cleaned_data['fotos']:
            att = Bulk(school=self.instance, file=each)
            att.save()

to views.py.

Chive commented 9 years ago

@marojenka sure that should be possible. In the simple example you can see a possible way to achieve this: https://github.com/Chive/django-multiupload/tree/master/examples/simple.