RebeccaRol
RebeccaRol

Reputation: 123

submitting 2 forms together, passing primary key from one as foreign key in other

I have created a form using python and django from 2 seperate modelForms in the one html template. Models:

class Action(models.Model):
    name = models.CharField("Action name", max_length=50)
    keywords = models.CharField("Keywords", max_length=50)
    object = models.CharField("Object", max_length=50, blank=True, null=True)
    uploadDate = models.DateField("Date", default=get_current_date)
    UploadedBy = models.CharField("UploadedBy", max_length=50, default="")

class Image(models.Model):
    image = models.FileField(upload_to=get_upload_file_name, default="") 
    action = models.ForeignKey(Action)

def get_upload_file_name(instance, filename):
    return "uploaded_files/%s_%s" % (str(datetime.now().day).replace('.','_'), filename)

forms:

class ActionForm(ModelForm):
    #bind form to Action model
    class Meta:
        model = Action
        fields = ['name','keywords', 'object', 'UploadedBy', 'uploadDate']

class ImageForm(ModelForm):
    class Meta:
        model= Image
        fields =['image']

The code which creates the form in views:

def actioncreate(request):
    if request.method == "GET":
        #create the object - Actionform 
        form = ActionForm;
        form2 = ImageForm;
        #pass into it 
        return render(request,'app/createForm.html', { 'form':form, 'form2':form2})
    elif request.method == "POST":
        # take all of the user data entered to create a new action instance in the table
        form = ActionForm(request.POST, request.FILES)
        form2 = ImageForm(request.POST, request.FILES)
        if  form.is_valid() and form2.is_valid():
            act = form.save(commit=False)
            img = form2.save(commit=False)
            #set the action_id Foreignkey 
            act.id = img.action_id                 
            act.save()
            img.save()
            return HttpResponseRedirect('/actions')
        else:
            form = ActionForm()
            form2 = ImageForm;
            return render(request,'app/createForm.html', { 'form':form, 'form2':form2 })

The form is created fine but when it is submitted, it trys to save image.id, image.image (filename) and returns null for image.action_id I am getting the error:

null value in column "action_id" violates not-null constraint
DETAIL:  Failing row contains (2, uploaded_files/29_personrunning_Hq8IAQi.jpg, null).   

I obviously need to populate the third column with the action.id which django creates itself on submitting the first part 'form'. Is there a way I can get the action.id value and populate the action_id field in the image table in the one form submission? image.action_id is declared initially as a foreignKey related to action in models.

Upvotes: 2

Views: 1003

Answers (1)

Pancho Jay
Pancho Jay

Reputation: 500

The first problem is related to act = form.save(commit=False) because it will return an object that hasn’t yet been saved to the database, then act doesn't have an ID. You need to save (and commit) act first.

Also there is another error in following line:

act.id = img.action_id  # It should be: img.action_id = act.id

You may want to assign act to img.action. Please note that you are doing it in the wrong way (you are assigning in img.action to act). The best way to do it is:

img.action = act  # This is equivalent to img.action_id = act.id

Try swapping these lines:

        act.save()
        img.action = act

Upvotes: 1

Related Questions