2015-11-21 20 views
18

新しく作成したModelFormの主キーを同じビューの別のフォームフィールドに渡す必要がありますが、エラーが発生します。この作品を作るための提案はありますか? それは、過去のように見える、これが答えのようになります。未保存の関連オブジェクトによるデータ損失を防ぐためにsave()を禁止

def contact_create(request): 
    if request.method == 'POST': 
     form = ContactForm(request.POST) 
     if form.is_valid(): 
      form.save() 
      return HttpResponseRedirect(reverse(contact_details, args=(form.pk,))) 
    else: 
     form = ContactForm() 

ドキュメントから、これは> 1.8.3

p3 = Place(name='Demon Dogs', address='944 W. Fullerton') Restaurant.objects.create(place=p3, serves_hot_dogs=True, serves_pizza=False)
Traceback (most recent call last):
...
ValueError: save() prohibited to prevent data loss due to unsaved related object 'place'.

新しいDjangoのバージョンで何が起こっているかである。これは私が私を取得しています方法ですビューからpk

my_id = "" 
if form.is_valid(): 
    # deal with form first to get id 
    model_instance = form.save(commit=False) 
    model_instance.pub_date= timezone.now() 
    model_instance.user= current_user.id 
    model_instance.save() 
    my_id = model_instance.pk 

if hourformset.is_valid(): 
    hourformset.save(commit=False) 
    for product in hourformset: 
     if product.is_valid(): 
      product.save(commit=False) 
      product.company = my_id 
      product.save() 
else: 
    print(" modelform not saved") 
return HttpResponseRedirect('/bizprofile/success') 
+1

2)product.company = model_instanceの代わりにproduct.company = my_idと同じ、3)エラーとは何ですか?1)なぜmodel_instance.userをcurrent_user.idに設定するのですか?あなたは(あなたが引用したValueErrorですか?)コード内のどの行になっていますか? –

+0

エラーは常にproduct.save()にあります。 – Godfrey

+0

save()は、保存されていない関連オブジェクト 'company'によるデータ損失を防ぐために禁止されています。私はあなたの提案を既に適用しました。 – Godfrey

答えて

8

これはDjango 1.8で導入されました。以前は、保存されていないインスタンスを1対1の関係に割り当てることができました。失敗した場合は、静かにスキップされました。この場合、Django 1.8からはエラーメッセージが表示されます。 Django 1.7 - > 1.8アップグレードのdocumentationを確認してください。

それは言う:あなたが詳細に興味がある場合は

Assigning unsaved objects to a ForeignKey, GenericForeignKey, and OneToOneField now raises a ValueError.

は、あなたがsave方法django.db.models.baseで確認することができます:それはいくつかの部分:

for field in self._meta.concrete_fields: 
    if field.is_relation: 
     # If the related field isn't cached, then an instance hasn't 
     # been assigned and there's no need to worry about this check. 
     try: 
      getattr(self, field.get_cache_name()) 
     except AttributeError: 
      continue 
     obj = getattr(self, field.name, None) 
     # A pk may have been assigned manually to a model instance not 
     # saved to the database (or auto-generated in a case like 
     # UUIDField), but we allow the save to proceed and rely on the 
     # database to raise an IntegrityError if applicable. If 
     # constraints aren't supported by the database, there's the 
     # unavoidable risk of data corruption. 
     if obj and obj.pk is None: 
      raise ValueError(
       "save() prohibited to prevent data loss due to " 
       "unsaved related object '%s'." % field.name 
      ) 

最終5行は、このエラーがどこにあるかあります育った。基本的にあなたの関連するobjは保存されませんobj.pk == NoneValueErrorが発生します。

7

それは簡単です:

p3 = Place(name='Demon Dogs', address='944 W. Fullerton') 
p3.save() # <--- you need to save the instance first, and then assign 
Restaurant.objects.create(
    place=p3, serves_hot_dogs=True, serves_pizza=False 
) 
+0

modelformインスタンスを保存していても同じ値のエラーが発生しています。私のコードを見て、なぜ私がこれを取得しているか教えてください:save()は、保存されていない関連オブジェクト 'company'によるデータ損失を防ぐことを禁じられています。 – Godfrey

3

回答済み - 問題は、空のフォームまたは変更されていないフォームを保存しないでdjangoから発生しました。これにより、保存されていないフォームのフィールドがNULLになりました。実際には、すべてのフィールドで、外部キーにヌルフィールドを許可することで問題を修正しました。そうすれば、空のフォームや変更されていないフォームは保存時にエラーを返さなかった。

FYI: @wolendranh answerを参照してください。

+0

これを読んでいる人に知らせてください。null値を持つことは、特にForeignKeysにとっては悪い考えです。 null値のみを使用すると意味があります(通常は決してありません)。 – llazzaro

+0

@llazzaroなぜこのような場合ですか、いくつかの説明やクレームへの参照ができますか? – unlockme

+0

@llazzaro、私はそのプロジェクトの内容を忘れていましたが、私はユーザーのために毎週の曜日に関連する7つのフォームを自動生成していました。ユーザーは、毎日の営業時間を記入しなければなりませんでした。当然、何日かは空でも変わらずに残っていました。私は以下の答えがこれを詳しく説明していると思います。疑問は、それらの空のフォームに対処する方法でした。 – Godfrey

関連する問題