Почему я получаю эту ошибку? 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()