我创建了一个表单并将外键“艺术家”设置为 CharField,这样用户就可以自由输入艺术家的名字,如果不存在则创建它。在艺术家字段中输入数据时出现以下错误:
ValueError: Cannot assign "'testing'": "Profile.artist" must be a "Artist" instance
这是我的模型.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()
请您参考如下方法:
clean_artist 方法应该返回艺术家字段的清理值。所以不是
artist, created = Artist.objects.get_or_create(name=artist)
self.cleaned_data['artist'] = artist
return super(ProfileForm, self).clean()
做
artist, created = Artist.objects.get_or_create(name=artist)
return artist
我不确定在 clean 方法中重写字段类型是否是最佳实践,因为如果表单中存在错误并且需要使用艺术家实例作为值再次呈现它可能会带来问题.
我可能会从 Meta.fields 中删除 artist 字段并执行 Artist.objects.get_or_create(name=artist) 并设置表单的 save 方法中实例的艺术家字段。
