2016-04-20 31 views
2

我創建了一個表單並將外鍵「藝術家」設置爲CharField,以便用戶可以自由輸入藝術家的姓名如果它不存在,它將被創建。在藝術家現場輸入數據時,我收到以下錯誤:Django ValueError無法指定「'測試'」:「Profile.artist」必須是「藝術家」實例

ValueError: Cannot assign "'testing'": "Profile.artist" must be a "Artist" instance

這裏是我的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

你當然不應該在'clean_artist'方法內調用超級'clean()'。該方法也不需要'commit'參數。 –

+0

'commit = True'參數不需要 – Sayse

回答

1

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 

我不知道但如果它是重寫一個字段的類型的清潔方法的最佳實踐,如是否有錯誤,它可能會帶來的問題該表單需要再次以藝術家實例作爲值再次呈現。

我可能會從Meta.fields刪除artist場並做Artist.objects.get_or_create(name=artist)並設置形式的save方法實例的藝術家現場。

+0

謝謝,它可以工作,但是當我從'Meta.fields'中刪除'artist'字段時,表單會在底部而不是窗體的頂部呈現藝術家字段。提交表單w /數據,我得到** profiles_profile.artist_id可能不是NULL ** – bayman

+0

您可以使用Form.field_order定義字段順序(https://docs.djangoproject.com/en/1.9/ref/forms /api/#django.forms.Form.field_order)從django 1.9開始。 – Tim

+0

您需要在窗體上添加一個'save()'方法,以在配置文件中手動設置藝術家。 – Tim

相關問題