On Aug 12, 9:20 pm, Tomek <tomasz.kustrzyn...@gmail.com> wrote:
> Hi,
>
> Question: Is there a better way of creating objects from formset
> (children) without having to create and possibly delete object which
> is referenced by them (parent) and which is being created on the same
> page?
>
> Here's my (simplified) models. It's basically an item with some
> pictures. It's just nice to have this on single form - fill
> description and add some pics.
>
> -----------------------------------------------------
> class Item(models.Model):
>    owner = models.ForeignKey(User)
>
> class ItemImage(models.Model):
>     image = ImageField()
>     item = models.ForeignKey(Item)
>
> -----------------------------------------------------
> And here's the view:
>
> -----------------------------------------------------
> def view_item_add(request):
>     ImageFormset = inlineformset_factory(Item, ItemImage,
> fk_name="item")
>     if request.method == 'POST':
>         item_form = ItemCreateForm(data=request.POST)
>         if item_form.is_valid():
>             item = item_form.save(commit=False)
>             item.owner = request.user
>             item.save()
>
>             # creating the 2nd form only now!
>             imageset_form = ImageFormset(data = request.POST,
> prefix='images', instance=item)
>             if imageset_form.is_valid():
>                 imageset_form.save()
>             else:
>                 # deleting item is formset items invalid - could we
> have avoided creating this temporary item in the first place?
>                 item.delete()
>     else:
>         # create empty forms....
>
>    return render_to_response(...)
>
> -----------------------------------------------------
>
> Thanks for having a look.
>
> Tomek


If I understand your issue correctly, it is that you want to be sure
that the user has added at least one image before creating the parent
item.

If that's right, I would tackle this via validation on the formset, so
that it is impossible to submit the form without any images. That's
easy to do, just create a custom formset subclass and override the
clean() method, checking that there's at least one form:

class ImageInlineFormset(BaseInlineFormSet):
    def clean(self):
        # get forms that actually have valid data
        count = 0
        for form in self.forms:
            try:
                if form.cleaned_data:
                    count += 1
            except AttributeError:
                # annoyingly, if a subform is invalid Django explicity
raises
                # an AttributeError for cleaned_data
                pass
        if not count:
            raise forms.ValidationError('You must have at least one
image')

Then use this ImageInlineFormset as the formset parameter to
inlineformset_factory in your view:

ImageFormset = inlineformset_factory(Item, ItemImage, fk_name="item",
                                     formset=ImageInlineFormset)

Now the user will get an error message if they post the form with no
images.
--
DR.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to