Search code examples
djangodjango-formsdjango-1.5generic-relations

Django 1.5 ModelForm like admin in view with images and foreign key


I have the following models:

class Quiver(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    is_default = models.BooleanField(default=False)
    type = models.CharField(max_length=1, choices=QUIVER_TYPES)
    category = models.CharField(max_length=255, choices=QUIVER_CATEGORIES)

    def __unicode__(self):
        return u'[%s] %s %s quiver' % (
            self.user.username,
            self.get_type_display(),
            self.get_category_display())


class Image(models.Model):
    photo = models.ImageField(upload_to=get_upload_file_path)
    is_cover = models.BooleanField(default=False)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

    def save(self, *args, **kwargs):
        try:
            this = Image.objects.get(pk=self.pk)
            if this.photo != self.photo:
                this.photo.delete(save=False)
        except Image.DoesNotExist:
            pass

        super(Image, self).save(*args, **kwargs)


class Surfboard(models.Model):
    quiver = models.ForeignKey(Quiver)
    brand = models.CharField(max_length=255)
    model = models.CharField(max_length=255)
    length = models.CharField(max_length=255)
    width = models.CharField(max_length=255, blank=True)
    thickness = models.CharField(max_length=255, blank=True)
    volume = models.CharField(max_length=255, blank=True)
    images = generic.GenericRelation(Image)

    def __unicode__(self):
        return u'%s %s %s' % (self.length, self.brand, self.model)

    def get_cover_image(self):
        "Returns the cover image from the images uploaded or a default one"
        for image in self.images.all():
            if image.is_cover:
                return image

        return None

I'd like to be able to have the same form I have in the admin in my frontend view /surfboard/add:

add surfboard with foreign key in dropdown and add images

As a new Django fan and user, I started to create the form from scratch. Not being able to do what I want with including the foreign key "quiver" as a dropdown list, I found in the doc the ModelForm, and decided to use it, so here what I got:

class SurfboardForm(ModelForm):
    class Meta:
        model = Surfboard

In my view, it looks like this and it's already a good start:

enter image description here

So now, I wanted to have a way to add pictures at the same time, and they are linked to a surfboard via a Generic Relation. Here I don't find the way to do a implementation like in the admin, and get frustrated. Any tips to do so?

Thanks!


Solution

  • What you seek is called an inline formset - see the docs for more.

    It's also handy that you can render a formset quickly with {{ formset.as_p }}, but you'll need to write some JavaScript (or use the JavaScript that's used in the Django admin) to handle adding and removing forms.