Почему я получаю эту ошибку? ValueError: Невозможно присвоить значение "'14'": "Jobs.category" должен быть экземпляром "Category".

Я пытаюсь добавить задания в базу данных через форму. Однако я получаю ошибку " ValueError: Cannot assign "'14'": "Jobs.category" должен быть экземпляром "Category"". Когда я отправляю форму. Я не уверен, как я могу решить эту проблему. Категория является внешним ключом в модели Jobs. Пользователь должен иметь возможность выбирать из категорий, уже существующих в базе данных. Это отображается в форме, однако при отправке. Выдается вышеуказанная ошибка. Я тут совсем запутался. Буду признателен за любое руководство.

forms.py

class JobForm(forms.ModelForm):

    CATEGORY_CHOICES = []        
    categories = Category.objects.all()
    for category in categories:
        CATEGORY_CHOICES.append((category.id, capwords(category.title)))

    title = forms.CharField(
                required = True,
                widget =  forms.TextInput(attrs = {'class': 'form-control ', 'placeholder': 'e.g Software Engineer'}),
                )

    category = forms.ChoiceField(
                choices = CATEGORY_CHOICES,
                required = True,
                widget = forms.Select(attrs = {'class': 'selectpicker border rounded', 'placeholder': 'select category'}),
                )
 
    class Meta:
        model = Jobs

        fields = [
            "title",
            "category",
        ]

models.py

class Category(models.Model):
    title = models.CharField(max_length= 200, null = True, blank = True)
    description = models.TextField(null = True, blank = True)
    uniqueId = models.CharField(null = True, blank = True, max_length = 100)
    categoryImage = models.ImageField(default = 'category.png', upload_to = 'upload_images')
    slug = models.SlugField(max_length = 500, unique=True, blank = True, null = True)
    
    class Meta:
        verbose_name_plural = "Categories"


class Jobs(models.Model):

    title = models.CharField(max_length=1000, null = True, blank = True)
    company = models.ForeignKey(Company, on_delete = models.CASCADE, null = True, blank = True)
    category = models.ForeignKey(Category, related_name= 'Category', on_delete = models.CASCADE, null = True, blank = True)
    location = models.CharField(max_length=1000, null = True, blank = True)
    salary = models.CharField(max_length=1000, null = True, blank = True)
    uniqueId = models.CharField(null = True, blank = True, max_length = 100)
    nature = models.CharField(max_length=100, choices=TYPE_CHOICES, default=NOT_PROVIDED)
    experience = models.CharField(max_length=100, choices=EXP_CHOICES, default=NOT_PROVIDED)
    summary = models.TextField(null = True, blank = True)
    description = models.TextField(null = True, blank = True)
    closing_date = models.DateField(blank = True, null = True)
    date_posted = models.DateField(blank = True, null = True)
    contract_type = models.CharField(max_length = 1000, null = True, blank = True)
    date_created = models.DateTimeField(default = timezone.now) 
    slug = models.SlugField(max_length = 1000, unique = True, blank = True, null = True)
 
    
    def __str__(self):
        return '{} - {}'.format(self.company, self.title)

    def get_absolute_url(self):
        return reverse('job-detail', kwargs = {'slug': self.slug})
    
    class Meta:
        verbose_name_plural = "Jobs"

views.py

def add_job(request): 
    if request.method == 'POST':
        form = JobForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            messages.success(request, 'Job added Successfully')
            return redirect('add-job')
        else:
            messages.error(request, 'Error Processing Your Request')
            context = {'form': form}
            return render(request, 'index.html', context)

    else:
        form = JobForm()
        context = {'form': form}
        return render(request, 'add-job.html', context)

Объект задания ожидает, что категория будет экземпляром модели Category, поскольку для нее определено отношение ForeignKey. Просто используйте ModelChoiceField вместо ChoiceField в форме.

class JobForm(forms.ModelForm):

    title = forms.CharField(
        required=True,
        widget=forms.TextInput(attrs={'class': 'form-control ', 'placeholder': 'e.g Software Engineer'}),
    )

    category = forms.ModelChoiceField(queryset=Category.objects.all(),
                                      required=True)

    class Meta:
        model = Jobs

        fields = [
            "title",
            "category",
        ]

Ответ Хелге здесь объясняет проблему.

Довольно часто лучше всего создавать реляционные поля косвенно, а не через ModelForm или ModelChoiceField. Вместо этого вы добавляете несколько нереляционных (символьные, числовые, дата и т.д.) полей формы и обрабатываете их для определения соответствующего отношения. Тогда схема кода будет выглядеть примерно так:

if form.is_valid():  # or subclass the form_valid method of a Class based view
    info1 = form.cleaned_data['info1']  # your added model fields
    info2 = form.cleaned_data['info2']
    # process info1 and info2 to identify the relevant object(s) needed
    # for the relation
    if( there_is_a_problem):
         form.add_error('info1', 'explain the problem')  
         # the form is now invalid. In a class-based view you can do
         return self.form_invalid( form)
    instance = form.save( commit=False)
    instance.relation =   # what you worked out above
    instance.save()
Вернуться на верх