MultipleObjects returned when selecting a choice and creating an object for it

45 views Asked by At

In my project I am using react for the frontend and django for the backend. I have the following models, which are related to the issue I am facing

class Role(models.Model):
    ROLE_CHOICES = (
        ('Recruiter', 'Recruiter'),
        ('Manager', 'Manager'),
        ('Business Development Partner', 'Business Development Partner'),
        ('Business Development Partner Manager', 'Business Development Partner Manager'),
        ('Account Manager', 'Account Manager'),
    )
    role = models.CharField(max_length=50, choices=ROLE_CHOICES, null=True, unique=True)

    def __str__(self):
        return self.name

class UserData(models.Model):
    fullName = models.CharField(max_length=255, blank=True, null=True)
    gender = models.CharField(max_length=10, blank=True, null=True)
    aadhaarNumber = models.CharField(max_length=12, blank=True, null=True)
    dateOfBirth = models.DateField(null=True, blank=True)
    maritalStatus = models.CharField(max_length=20, blank=True, null=True)
    emergencyContact = models.CharField(max_length=255, blank=True, null=True)
    address = models.TextField(blank=True, null=True)
    phoneNumber = models.IntegerField(validators=[MinValueValidator(0000000000), MaxValueValidator(9999999999)], blank=True, null=True)
    emailID = models.EmailField(validators=[EmailValidator()], blank=True, null=True)
    emergencyContactNumber = models.IntegerField(validators=[MinValueValidator(0000000000), MaxValueValidator(9999999999)], blank=True, null=True)
    jobTitle = models.CharField(max_length=100, blank=True, null=True)
    departmentName = models.CharField(max_length=100, blank=True, null=True)
    joiningDate = models.DateField(blank=True, null=True)
    employmentType = models.CharField(max_length=100, blank=True, null=True)
    prevCompany = models.CharField(max_length=255, blank=True, null=True)
    prevDesignation = models.CharField(max_length=100, blank=True, null=True)
    relevantSkills = models.TextField(blank=True, null=True)
    documentAcknowledged = models.BooleanField(default=False, null=True)
    pfUAN = models.CharField(max_length=100, blank=True, null=True)
    esiNO = models.CharField(max_length=100, blank=True, null=True)
    role = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return self.fullName if self.fullName else "Unnamed User"
    
class LoginDetails(models.Model):
    user_data = models.OneToOneField(UserData, on_delete=models.CASCADE, null = True)
    username = models.CharField(max_length=255, unique=True, null=True)
    password = models.CharField(max_length=255, null=True)  # Note: It's recommended to use hashed passwords in production
    def __str__(self):
        return self.username


class Education(models.Model):
    user = models.ForeignKey(UserData, related_name='education', on_delete=models.CASCADE)
    degree = models.CharField(max_length=255)
    graduationYear = models.IntegerField(validators=[MinValueValidator(1960), current_year_validator])
    grade = models.CharField(max_length=10)

    def __str__(self):
        return f"{self.user.fullName}'s Education"


class WorkExperience(models.Model):
    user = models.ForeignKey(UserData, related_name='work_experience', on_delete=models.CASCADE)
    companyName = models.CharField(max_length=255)
    designation = models.CharField(max_length=100)
    duration = models.CharField(max_length=100)

    def __str__(self):
        return f"{self.user.fullName}'s Work Experience"

The views associated are as follows

def submit_user_data(request):
    if request.method == 'POST':
        data = request.POST

        # Get or create the Role object based on the selected role name
        role_name = data.get('role')
        role, created = Role.objects.get_or_create(role=role_name)

        # Create UserData object with the retrieved role
        user_data = UserData.objects.create(
            fullName=data.get('fullName'),
            gender=data.get('gender'),
            aadhaarNumber=data.get('aadhaarNumber'),
            dateOfBirth=data.get('dateOfBirth'),
            maritalStatus=data.get('maritalStatus'),
            emergencyContact=data.get('emergencyContactName'),
            address=data.get('address'),
            phoneNumber=data.get('phoneNumber'),
            emailID=data.get('emailID'),
            emergencyContactNumber=data.get('emergencyContactNumber'),
            jobTitle=data.get('jobTitle'),
            departmentName=data.get('departmentName'),
            joiningDate=data.get('joiningDate'),
            employmentType=data.get('employmentType'),
            relevantSkills=data.get('relevantSkills'),
            pfUAN=data.get('pfUAN'),
            esiNO=data.get('esiNO'),
            documentAcknowledged=data.get('documentAcknowledged'),
            role=role,
        )

        education_data = data.getlist('education')
        for edu in education_data:
            Education.objects.create(
                user=user_data,
                degree=edu.get('degree'),
                graduationYear=edu.get('graduationYear'),
                grade=edu.get('grade'),
            )

        # Create WorkExperience objects
        work_experience_data = data.getlist('workExperience')
        for exp in work_experience_data:
            WorkExperience.objects.create(
                user=user_data,
                companyName=exp.get('companyName'),
                designation=exp.get('designation'),
                duration=exp.get('duration'),
            )
        return JsonResponse({'id': user_data.pk, 'created': created})

    return JsonResponse({'error': 'Invalid request method'}, status=405)

def role_choices(request):
    roles = [{'id': key, 'role': role} for key, role in Role.ROLE_CHOICES]
    return JsonResponse(roles, safe=False)

Now I have a webpage, which is a form which deals with a new employee registration. I have roles in my system, such that each user is assigned one. I was able to retrieve the role choices from my model using the role_choices view. And now In my form I am selecting the role for the user and then I want to submit to the backend such that the role is linked to the user data model as well as the login details model.

Here is frontend page for it (Only posting the required here)

const handleSubmit = (event) => {
    event.preventDefault();
    
    // Make an HTTP POST request using Axios
    axios.post('http://127.0.0.1:8000/submit_user_data/', userData)
      .then(response => {
        console.log('Data sent successfully:', response.data);
        // Reset the form after successful submission
        setUserData({ ...userData});
        navigate('/usernameregistration');
      })
      .catch(error => {
        console.error('Error sending data:', error);
      });
  };

<label>
          Select Role:
          <select
            name="role"
            value={userData.role}
            onChange={handleInputChange}
          >
            <option value="">Select</option>
            {roleOptions.map(role => (
              <option key={role.id} value={role.role}>
                {role.role}
              </option>
            ))}
          </select>
        </label>

When the submit_user_data view is called I get the following error on my console

<h1>MultipleObjectsReturned
       at /submit_user_data/</h1>
  <pre class="exception_value">get() returned more than one Role -- it returned 4!</pre>

I am not sure where I am going wrong

0

There are 0 answers