Reputation: 310
I almost tried every ideas that I found on the internet, but it is still not working,
class RankedSkill(models.Model):
RANK_CHOICES = (
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8),
(9, 9),
(10, 10),
)
skill = models.ForeignKey(Skill, related_name='ranks')
rank = models.IntegerField(max_length=2, choices=RANK_CHOICES)
assessment = models.ForeignKey(Assessment, related_name='skill_ranks')
)
Assessment and Skill are another models. In my app, I want to create forms for every skill to rank them. I used django formset for that, I create a formset from RankedSkillForms with initial data that I got with Skill.objects.all().
skills = Skill.objects.all()
SkillFormSet = formset_factory(SkillRankForm, max_num=skills.count())
if request.method == 'POST':
formset = SkillFormSet(request.POST)
if formset.is_valid:
person = get_object_or_404(People, id=person_id)
assessment = Assessment.objects.create(supervisor=request.user, employee=person)
for form in formset.forms:
ranked_skill = form.save() # error coming from here
ranked_skill.assessment = assessment
ranked_skill.save()
else:
return render(request, 'people/make_assessment.html', {'formset': formset})
else:
initial = []
for skill in skills:
initial.append({'skill': skill})
formset = SkillFormSet(initial=initial)
return render(request, 'people/make_assessment.html', {'formset': formset})
Everything works fine until I tried to save.
It gets the initial data (Skill) as u'Skill Object' string. (I removed the unicode, because before that name of the skill was coming instead of u'Skill Object' string)
Error message is "Cannot assign "u'Skill object'": "RankedSkill.skill" must be a "Skill" instance."
Upvotes: 0
Views: 2778
Reputation: 118458
Your SkillRankForm
is accepting strings instead of PKs or instances.
You need to either...
Modify the form to use PKs and not Text such as with skills = forms.ModelChoiceField
Or coerce the incoming string into a Skill object in your form (or view, even).
ranked_skill = form.save(commit=False)
skill, created = Skill.objects.get_or_create(name=form.cleaned_data['skill'])
#^^^^ assuming there's a name field
ranked_skill.skill = skill
ranked_skill.save()
Also one more thing... you should fix your formset validation:
if formset.is_valid:
#^^^ you need to call is_valid() or this will always return True.
Upvotes: 1