Django ValueError无法指定“'testing'”:“Profile.artist”必须是“Artist”实例

时间:2016-04-20 07:43:58

标签: python django

我创建了一个表单,并将外键“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()

1 个答案:

答案 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方法中设置实例的艺术家字段。