On Wed, Jan 27, 2010 at 14:04, andreas schmid <a.schmi...@gmail.com> wrote:

> is this an add or an edit form? or both?
>
> i have a similar inlineformset and i need to loop over the inline
> objects to set the foreignkey to the parent object like:
>
>    if form.is_valid() and formset.is_valid(): # All validation rules pass
>                new_idea = form.save(commit=False)
>                new_idea.author = request.user
>                new_idea = form.save()
>                formset_models = formset.save(commit=False)
>                for f in formset_models:
>                    f.idea = new_idea
>                    f.save()
>                return HttpResponseRedirect(new_idea.get_absolute_url())
>
>
> im actually experiencing problems with the edit form where i can get the
> values displayed in the form if i want to edit but i get a
>
>    Exception Type:     MultiValueDictKeyError
>    Exception Value:
>
>    Key 'activity_set-0-id' not found in <QueryDict:
> {u'activity_set-0-name': [u'a\xf6lskjdf\xf6sa'], u'activity_set-0-type':
> [u'research']
>
> on save... any hints?
>
>
> Stefan Nitsche wrote:
> > On Mon, Jan 4, 2010 at 23:27, Stefan Nitsche <ste...@nitsche.se
> > <mailto:ste...@nitsche.se>> wrote:
> >
> >     Hi,
> >
> >     to begin with I would like to declare that I'm still on the
> >     beginner end of the scale when it comes to Python and Django.
> >
> >     I have an app which has two models:
> >
> >     class Item(models.Model):
> >         title = models.CharField()
> >         description_markdown = models.TextField()
> >
> >     class ItemImage(models.Model):
> >         item = models.ForeignKey(Item)
> >         image = models.ImageField(upload_to='tmp')
> >
> >     What I want to do now is to create a page where users can submit
> >     an item and upload an image (or images) at the same time. I can
> >     create a form using ModelForm for the Item-model and I can create
> >     a form for the ItemImage-model using inlineformset_factory, if I
> >     do this the submit page looks like it should. However it doesn't
> >     behave the way I want it to when saving, but to be honest I have
> >     no real idea of what I'm doing when it comes to the related
> >     model/form.
> >
> >     If I understand it correctly when using inlineformset_factory I
> >     must give it an instance so that it can map the foreignkey,
> >     correct? So how do one go about and create a form where people can
> >     add "item" and "itemimages" at the same time? I'm feeling totaly
> >     lost any pointers would be greatly appreciated.
> >
> >     --
> >     Stefan Nitsche
> >     ste...@nitsche.se <mailto:ste...@nitsche.se>
> >
> >
> >
> > Ok I'm totally lost here. I've created an edit function which works
> > splendidly except for the inline-part, it displays alright but it
> > isn't saved at all.
> >
> > My models look like this:
> > ==================
> >
> > class Recipe(models.Model):
> >     author = models.ForeignKey(User)
> >     name = models.CharField(max_length=255, verbose_name='Namn på
> rätten')
> >     category = models.ForeignKey('Category', verbose_name='Kategori')
> >     create_date = models.DateTimeField(auto_now_add=True)
> >     servings = models.CharField(max_length=10, verbose_name='Portioner')
> >     cooking_time = models.CharField(max_length=10,
> > verbose_name='Tillagningstid')
> >     ingredients = models.TextField(verbose_name='Ingridienser')
> >     instructions = models.TextField(verbose_name='Instruktioner')
> >     oven_heat = models.CharField(max_length=10, null=True, blank=True,
> > verbose_name='Ugnsvärme')
> >     serving_tips = models.TextField(null=True, blank=True,
> > verbose_name='Serveringsförslag')
> >     tags = TagField(verbose_name='Taggar')
> >     slug = models.SlugField()
> >     published = models.NullBooleanField(default=1)
> >
> > class Image(models.Model):
> >     recipe = models.ForeignKey(Recipe)
> >     file = models.ImageField(upload_to=get_file_path)
> >
> > My view looks like this:
> > =================
> > from django.shortcuts import render_to_response, get_object_or_404
> > from django.template import RequestContext
> > from django.http import HttpResponseRedirect
> > from nitsche.recipes.models import Category, Recipe, Image
> > from nitsche.recipes.forms import RecipeForm
> > from django.contrib.auth.decorators import login_required
> > from django.forms.models import inlineformset_factory
> >
> > @login_required
> > def edit(request, slug):
> >     ImageFormSet = inlineformset_factory(Recipe, Image)
> >     recipe = Recipe.objects.filter(published=True).get(slug=slug)
> >     form = RecipeForm(instance=recipe)
> >     formset = ImageFormSet(instance=recipe)
> >     if request.method == 'POST':
> >         form = RecipeForm(request.POST, instance=recipe)
> >         formset = ImageFormSet(request.POST, request.FILES,
> > instance=recipe)
> >         if form.is_valid(): # All validation rules pass
> >             form.save()
> >         if formset.is_valid():
> >             formset.save()
> >         return HttpResponseRedirect('/recept')
> >     return render_to_response('recipes/add.html',
> >                               {'form': form, 'formset': formset,
> > 'slug':slug,},
> >                               context_instance=RequestContext(request))
> >
> > And finaly my template looks like this:
> > ============================
> >
> > <form action="/recept/edit/{{ slug }}/" method="POST">
> > {{ form.as_p }}
> > <table>
> > {{ formset }}
> > </table>
> > <input type="submit" value="Submit" />
> > </form>
> >
> > Every change I make in the main form (for the recipe-model) is saved
> > but nothing from the inline_formset (the image-model). I get no error
> > or anything, it behaves as if it is saving all the data but in the
> > reality nothing in the inline_formset is saved. I've read the
> > documentation and as far as I understand it should work this way. When
> > I add or edit an item in the backend it works as it should. Can
> > somebody point out what I'm doing wrong? At this point I am starting
> > to feel a little desperate and any nudge in the right direction would
> > be greatly appreciated.
> >
> > --
> > Stefan Nitsche
> > ste...@nitsche.se <mailto:ste...@nitsche.se>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Django users" group.
> > To post to this group, send email to django-us...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > django-users+unsubscr...@googlegroups.com<django-users%2bunsubscr...@googlegroups.com>
> .
> > For more options, visit this group at
> > http://groups.google.com/group/django-users?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To post to this group, send email to django-us...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users+unsubscr...@googlegroups.com<django-users%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>
>
I can understand your confusion since in my first post I was trying to
create an add form and in my second email I changed it to be an edit form
(since I figured it would be easier to get going).

I've actually solved my problem now. First: thanks to you I got on the right
track. Second: I'm stupid.

After I had changed the save function to mimic yours and it still didn't
work I started to print every variable I could find. After some trials and
more prints I discovered that request.FILES was empty.
Adding enctype="multipart/form-data" to the form in the template solved
that embarrassingly stupid error.

I am now able to add and edit items from the frontend. Here is how my
view-function and my template looks like (for now):

views.py
======
def edit(request, category=None, slug=None):
    ImageFormSet = inlineformset_factory(Recipe, Image)
    if slug is not None:
        recipe = Recipe.objects.filter(published=True).get(slug=slug)
        form = RecipeForm(instance=recipe) # A bound form
        formset = ImageFormSet(instance=recipe)
    else:
        form = RecipeForm() # An unbound form
        formset = ImageFormSet(instance=None)
    if request.method == 'POST': # If the form has been submitted...
        if slug is not None:
            form = RecipeForm(request.POST, instance=recipe) # A form bound
to the POST data
            formset = ImageFormSet(request.POST, request.FILES,
instance=recipe) # An inline formset bound to the POST and FILES data
        else:
            form = RecipeForm(request.POST, instance=None) # A form bound to
the POST data
            formset = ImageFormSet(request.POST, request.FILES,
instance=None) # An inline formset bound to the POST and FILES data
        if form.is_valid() and formset.is_valid(): # All validation rules
pass
           new_recipe = form.save(commit=False)
           new_recipe = form.save()
           if slug is None:
               formset = ImageFormSet(request.POST, request.FILES,
instance=new_recipe) # An inline formset bound to the POST and FILES data
           formset_models = formset.save(commit=False)
           for f in formset_models:
               f.recipe = new_recipe
               f.save()
           #return HttpResponseRedirect(reverse('recipes-index',)) #
Redirect after POST
           return HttpResponseRedirect(new_recipe.get_absolute_url())
    return render_to_response('recipes/edit.html',
                              {'form': form, 'formset': formset,
'slug':slug, 'category':category,},
                              context_instance=RequestContext(request))

edit.html
======
<form action="{% if slug %}{% url recipes-edit category slug %}{% else %}{%
url recipes-add %}{% endif %}" method="POST" enctype="multipart/form-data">
{{ form.as_p }}

<h2>Ladda upp bild(er)</h2>
<table>
{{ formset }}
</table>
<input type="submit" value="Submit" />
</form>

-- 
Stefan Nitsche
ste...@nitsche.se

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@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