I’m working on a project which creates a portfolio for a user based on the information they input in the form. The infomation is sent using AJAX . When a user signs in for the first time and inputs their information, the information is saved and everything runs smoothly. But when the user tries to update infomation an error is triggered. This is the trace back below.
Traceback (most recent call last):
File "/home/jojoe/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in
_execute
return self.cursor.execute(sql, params)
File "/home/jojoe/.local/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 396,
in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: portfolio_person.user_id
The neccesary code is below.
The views
import json
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Person, Occupation, WorkExp, AcadExp, Contact, Skills
def portfolio(request):
return render(request, 'portfolio/portfolio.html')
@login_required
def portfolio_form(request):
if request.method == 'POST':
first_name=request.POST.get('firstName')
last_name=request.POST.get('lastName')
person = Person(first_name=first_name, last_name=last_name, user=request.user)
person.save()
job=request.POST.get('occupation')
occupation=Occupation(occupation=job, user=request.user)
occupation.save()
skillsInfo=request.POST.get('skill')
abilities=skillsInfo.split(',')
for ability in abilities:
skills=Skills(skills=ability, occupation_id=request.user.occupation.id)
skills.save()
workInfo=request.POST.get('workexp')
works=json.loads(workInfo)
for work in works:
workexp=WorkExp(company=work['company'], started=work['started'], left=work['left'], position=work['position'], user=request.user)
workexp.save()
acadInfo=request.POST.get('acadexp')
academics=acadInfo.split(',')
for acad in academics:
acadexp=AcadExp(education=acad, user=request.user)
acadexp.save()
cell=request.POST.get('cell')
twitter=request.POST.get('twitter')
instagram=request.POST.get('instagram')
linkedin=request.POST.get('linkedin')
contact=Contact(cell=cell, twitter=twitter, instagram=instagram, linkedin=linkedin, user=request.user)
contact.save()
return redirect('portfolio')
messages.success(request, f'Your portfolio has been updated')
The ajax
let newSkills;
let newAcadExps;
let newWorkExps;
let skills = [];
let workExps = [];
let acadExps = [];
const addSkill=(ev)=> {
ev.preventDefault()
const skill = document.getElementById("skills").value;
skills.push(skill);
console.log(skills)
newSkills= skills.join(",");
document.getElementById("skills").value = "";
};
const addWorkExp=(ev)=>{
ev.preventDefault();
const workexp = {
company: document.getElementById("company").value,
started: document.getElementById("started").value,
left: document.getElementById("left").value,
position: document.getElementById("position").value,
};
workExps.push(workexp);
newWorkExps=JSON.stringify(workExps)
console.log(newWorkExps);
document.getElementById("company").value = "";
document.getElementById("started").value = "";
document.getElementById("left").value = "";
document.getElementById("position").value = "";
};
const addAcadExp=(ev)=>{
ev.preventDefault();
const acadexp = document.getElementById("education").value;
acadExps.push(acadexp);
newAcadExps = acadExps.join(",");
document.getElementById("education").value = "";
};
$("#form-id").submit(function (e) {
e.preventDefault();
$.ajax({
type:'POST',
url:'',
data:{
firstName : $('#first_name').val(),
lastName : $('#last_name').val(),
occupation : $('#occupation').val(),
cell : $('#cell').val(),
twitter : $('#twitter').val(),
instagram : $('#instagram').val(),
linkedin : $('#linkedin').val(),
skill : newSkills,
workexp : newWorkExps,
acadexp : newAcadExps,
},
success:function(){
alert("your form has been submitted")
}
})
});
const csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("addskill").addEventListener("click", addSkill);
document.getElementById("addwork").addEventListener("click", addWorkExp);
document.getElementById("addacademics").addEventListener("click", addAcadExp);
});
The models.
from django.db import models
from django.contrib.auth.models import User
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
display_picture = models.ImageField(default='default.png', upload_to='display_pictures')
#change default jpeg#
def __str__(self):
return f'{self.user.username} \'s info'
class Occupation(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, blank=True)
occupation = models.CharField(max_length = 100)
def __str__(self):
return f'{self.user.username} \'s occupation'
class Skills(models.Model):
occupation = models.ForeignKey(Occupation, on_delete=models.CASCADE)
skills = models.CharField(max_length = 100, blank=True)
def __str__(self):
return f'{self.occupation} \'s skillset'
class WorkExp(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
company = models.CharField(max_length = 200, blank=True)
started = models.IntegerField(null=True, blank=True)
left = models.IntegerField(null=True, blank=True)
position = models.CharField(max_length = 200, blank=True)
def __str__(self):
return f'{self.user.username} \'s work experiences'
class AcadExp(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
education = models.CharField(max_length = 30, blank=True)
def __str__(self):
return f'{self.user.username} \'s academic experiences'
class Contact(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
cell = models.IntegerField()
twitter = models.CharField(max_length = 100)
instagram = models.CharField(max_length = 100)
linkedin = models.CharField(max_length=100)
def __str__(self):
return f'{self.user.username} \'s contact information'