Django: Form.save () INSERT no funcionará, solo ACTUALIZAR

ok, so I go to the view for 'employment_add', I enter values in the fields of a Django form, then submit.

Success, It creates a new employment record and the page reloads with an empty form.

When I enter values and submit the second time, it updates; even though I am not passing an instance to the form and it is unbound.

I would like it to create a new employment record instead.

¿Alguna sugerencia? Gracias por tu ayuda.

---ACTUALIZAR---

Following on from Rajiv's answer: I don't understand where Django is getting the uuid of the previous object from. can anyone explain where in the RequestContext this information is being stored? There is no uuid(pk) field in the form or POST data, and I can't find it anywhere in the RequestContext. I am not passing an instance to the Form in either scenario... any explanation would be much appreciated

---UPDATE--- The issue appears to be at the instanciation of Employment, in the employment_add view. Please see the pdb trace below the code

===MODELS===

###User Model is provided by Django

import uuid
def make_uuid():
    return str(uuid.uuid4())

class __base__(models.Model):
    uuid = models.CharField(max_length=36, primary_key=True,
      default=make_uuid(), editable=False)
        #max_length must be 36. uuid4 generates a 36 character key

    class Meta:
        abstract = True

class Employment(__base__):
    user = models.ForeignKey( User, related_name='employment')
    ### employment related fields - no other PK or FK

===FORM===
class EmploymentForm(ModelForm):
class Meta:
    model = Employment
    exclude = ('user')
    widgets = {
    }

===VIEW===
def employment_add(request):
    context_instance = RequestContext(request)
    u = request.user
    if request.method == 'POST':
        message=""
        form = EmploymentForm(request.POST)
        if form.is_valid():
            f = form.save(commit=False)
            f.user = u
            f.save()
            message = "Position Added"
            form = EmploymentForm()
        return render_to_response("employment_add.html", {'form':form,    'message':message}, context_instance)
    else:
        em = Employment()
        #start pdb trace here
        form = EmploymentForm(instance=em)
    return render_to_response("employment_add.html", {'form': form},   context_instance)

===pdb trace===

(Pdb) em
<Employment: Employment object>
(Pdb) em.uuid
u'260015bc-c2eb-4cc1-9506-75e312027404'  
(Pdb) c

[29/Aug/2011 14:15:25] "GET /person/employment/add HTTP/1.1" 200 4425

[29/Aug/2011 14:15:33] "POST /person/employment/add HTTP/1.1" 302 0
<QueryDict: {u'month_start': [u''], u'year_start': [u''], u'year_end': [u''], u'employer': [u'66'], u'details': [u'6'], u'month_end': [u''], u'position': [u'66'], u'csrfmiddlewaretoken': [u'9e9c6b2ac43c370f993cb3f72682c7ea'], u'city_town': [u'']}>

[29/Aug/2011 14:15:33] "GET /person/view?i=1 HTTP/1.1" 200 9255
(Pdb) em
<Employment: Employment object>
(Pdb) em.uuid
u'260015bc-c2eb-4cc1-9506-75e312027404'
(Pdb) 

preguntado el 28 de agosto de 11 a las 05:08

Can you post your full model? -

Yes sorry - I forgot to show the base class which Employment inherits from. This base class is responsible for creating the uuid (PK) of the object. -

Rajiv, I have also added a trace showing where I think the problem is. Any idea why the new instance is not being assigned a new uuid? -

2 Respuestas

El problema parece ser el default=make_uuid(). Esto corre make_uuid only once, on model class creation, and passes the one generated value (not the function) as the default value for the field. Every time you create an instance, the same default value is used.

You should pass a callable as the default instead, as in: default=make_uuid.

Respondido 29 ago 11, 23:08

Much easier to see now that you've posted the whole models file - rczajka has the correct answer. - Rajiv Makhijani

sorry about that Rajiv - I will know better next time. Thank you both for your help! Problem solved. - just__matt

In the end of your code:

else:
    form = EmploymentForm()
return render_to_response("employment_add.html", {'form': form},   context_instance)

eliminar el context_instance from the call to render_to_response. This context instance contains the submitted form data and is pre-populating the form the second time.

Respondido 28 ago 11, 09:08

Hi Rajiv, I tried this but now it forgets the user.is_authenticated and has no csrf token. To provide more context to the question, even if I leave the 'employment_add' view and then come back to it from another page, the form will still only update the latest row in the table with the new values submitted by the form. Any other ideas? - just__matt

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.