我创建了一个表单,并将外键“artist”设置为CharField,因此用户可以自由输入艺术家的名字,如果它不存在则会创建它。在艺术家字段中输入数据时出现以下错误:
ValueError:无法指定“'testing'”:“Profile.artist”必须是“艺术家”实例
这是我的models.py:
class Artist (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Genre (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Profile (models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
genre = models.ForeignKey(Genre, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
mix = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.title
这是我的views.py:
def profile_create(request):
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
form = ProfileForm(None) #clears the form for new submission
context = {
"form": form,
"instance": instance,
}
return render(request, "profile_form.html", context)
else:
form = ProfileForm(None)
context = {
"form": form,
}
return render(request, "profile_form.html", context)
这是我的forms.py:
from django import forms
from .models import Profile, Artist
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = [
"artist",
"title",
"mix",
"genre",
]
artist = forms.CharField(widget=forms.TextInput)
def clean_artist(self, commit=True):
artist = self.cleaned_data.get("artist")
if not artist:
raise forms.ValidationError("Artist is a required field.")
else:
artist, created = Artist.objects.get_or_create(name=artist)
self.cleaned_data['artist'] = artist
return super(ProfileForm, self).clean()
答案 0 :(得分:1)
clean_artist
方法应该返回艺术家字段的清理值。所以而不是
artist, created = Artist.objects.get_or_create(name=artist)
self.cleaned_data['artist'] = artist
return super(ProfileForm, self).clean()
DO
artist, created = Artist.objects.get_or_create(name=artist)
return artist
我不确定是否最佳做法是在clean方法中重写字段的类型,因为如果表单中存在错误并且需要使用艺术家实例作为值再次呈现它,则可能会出现问题
我可能会从artist
中移除Meta.fields
字段并执行Artist.objects.get_or_create(name=artist)
并在表单的save
方法中设置实例的艺术家字段。