选择一个选项并为其创建对象时返回多个对象

问题描述 投票:0回答:1

在我的项目中,我使用 React 作为前端,使用 django 作为后端。我有以下模型,它们与我面临的问题相关

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"

关联视图如下

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>

我不知道我哪里错了

reactjs django django-models django-views
1个回答
0
投票

您遇到的错误似乎是由于

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
错误。

© www.soinside.com 2019 - 2024. All rights reserved.