Возврат нескольких объектов при выборе варианта и создании для него объекта

В моем проекте я использую react для фронтенда и django для бэкенда. У меня есть следующие модели, которые связаны с проблемой, с которой я столкнулся

Связанные с ними представления следующие

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)

Сейчас у меня есть веб-страница, которая представляет собой форму, занимающуюся регистрацией нового сотрудника. В моей системе есть роли, так что каждому пользователю назначается одна из них. Я смог получить варианты ролей из моей модели с помощью представления role_choices. И теперь в своей форме я выбираю роль для пользователя, а затем хочу отправить ее в бэкенд таким образом, чтобы роль была связана с моделью данных пользователя, а также с моделью данных для входа в систему.

Вот страница фронтенда для него (здесь размещается только то, что необходимо)

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>

При вызове представления submit_user_data я получаю следующую ошибку на консоли

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

Я не уверен, где я ошибаюсь

Похоже, что ошибка, с которой вы столкнулись, связана с методом get_or_create в вашем представлении submit_user_data, в частности при попытке получить объект Role на основе выбранного имени роли. Сообщение об ошибке указывает на то, что метод get() возвращает несколько объектов Role, а не один.

Скорее всего, проблема возникает из-за того, что вы используете get_or_create без указания ограничения уникальности для поля role в вашей модели Role. Хотя вы задали unique=True для поля role, это ограничение уникальности не выполняется на уровне базы данных, поскольку поле role является нулевым (null=True). Поэтому можно создать несколько Role объектов с null ролями.

Чтобы решить эту проблему, вы можете либо снять ограничение null=True с поля role в модели Role, либо изменить вызов get_or_create для обработки случая, когда для выбранного имени роли существует несколько Role объектов.

Вариант 1: Снять null=True ограничение с role поля в Role модели:

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, unique=True)  # Remove null=True

    def __str__(self):
        return self.name

Вариант 2: Обработка нескольких Role объектов в get_or_create вызове:

role_name = data.get('role')
try:
    role = Role.objects.get(role=role_name)
except Role.MultipleObjectsReturned:
    # Handle case where multiple Role objects exist for the selected role name
    # You may want to choose one of the Role objects or display an error message
    # For simplicity, I'm choosing the first Role object
    role = Role.objects.filter(role=role_name).first()

# If no Role object exists for the selected role name, create a new one
if not role:
    role = Role.objects.create(role=role_name)

Выберите вариант, который лучше всего соответствует вашим требованиям, и обновите код соответствующим образом. Это должно устранить ошибку MultipleObjectsReturned, с которой вы столкнулись.

Вернуться на верх