2016-04-03 22 views
1

私は最初のDjangoプロジェクトに問題があります。これは一般的な/簡単な解決策でなければなりません!背景のビットとして、私は治療の予定を追跡するために使用されるアプリケーションを構築しています。データ構造の大部分は、この1つのインスタンス(ManyToManyが必要であり、intemediary(through)モデルが必要です)を除いて、かなり単純です。下の私のmodels.pyに見られるように、私が持っている問題に関連する3つのモデルがあります。連絡先モデルは、顧客の連絡先の詳細を格納するために使用されます。ケースモデルは、仕事/仕事のコンセプトを扱うことです。特定のケースは複数のセッションを持つことができます。ケースに2人以上の連絡先があり、それらの間で請求書を分割するシナリオがしばしばあります。したがって、その特定の連絡先が支払う予定の請求書の割合を格納するために、義務モデルを持つManyToManyの必要性。 models.pyDjangoジェネリックビューManyToMany with "through"モデル

class Contact(models.Model): 
    first_name = models.CharField(max_length=200) 
    last_name = models.CharField(max_length=200) 
class Case(models.Model): 
    invoicees = models.ManyToManyField(Contact, through='Invoicees_Members', through_fields=('case','contact'),null=True, blank=True) 
class Invoicees_Members(models.Model): 
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE) 
    case = models.ForeignKey(Case, on_delete=models.CASCADE) 
    invoice_percentage = models.IntegerField(validators = [MinValueValidator(1), MaxValueValidator(100)],null=True, blank=True) 

私はstackoverflowのとフォームの送信を保存処理する方法の他のサイト上での周りの検索のかなり多くをやりました。最も一般的な解決策は、私が以下で実装しようとしているものと思われます。私はジェネリッククラスベースのビュー(この場合はCreateView)を使用しようとしています。 「例外値:保存()により保存されていない関連するオブジェクトの場合」にデータの損失を防ぐために禁止」残念ながら、次のエラーでフォームの送信結果が

views.py

class CaseCreate(CreateView): 
    model = Case 
    success_url = '/cases/' 
    fields = '__all__' 
    def form_valid(self, form): 
     self.instance = form.save(commit=False) 
     for contact in form.cleaned_data['invoicees']: 
      invoicee = Invoicees_Members() 
      invoicee.case = self.instance 
      invoicee.contact = contact 
      invoicee.save() 
     return super(ModelFormMixin, self).form_valid(form) 

。私の推測は、何らかの理由でform.save(commit = False)がInvoicees_Membersモデルに使用するIDを返さないということです...

何か考えていますか?私はここで間違っていることは自明なものでなければならない。 P.S. self.instanceの代わりにself.objectを使ってみましたが、同じエラーが発生しました。

エラー&スタックトレース:

Traceback: 

File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response 
    149.      response = self.process_exception_by_middleware(e, request) 

File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response 
    147.      response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "C:\Python27\lib\site-packages\django\views\generic\base.py" in view 
    68.    return self.dispatch(request, *args, **kwargs) 

File "C:\Python27\lib\site-packages\django\views\generic\base.py" in dispatch 
    88.   return handler(request, *args, **kwargs) 

File "C:\Python27\lib\site-packages\django\views\generic\edit.py" in post 
    256.   return super(BaseCreateView, self).post(request, *args, **kwargs) 

File "C:\Python27\lib\site-packages\django\views\generic\edit.py" in post 
    222.    return self.form_valid(form) 

File "C:\Users\danie\Documents\django-projects\office_management\officeman\views.py" in form_valid 
    40.   invoicee.save() 

File "C:\Python27\lib\site-packages\django\db\models\base.py" in save 
    651.       "unsaved related object '%s'." % field.name 

Exception Type: ValueError at /cases/add 
Exception Value: save() prohibited to prevent data loss due to unsaved related object 'case'. 

答えて

0

あなたは、請求書のインスタンスを保存する前に、ケースのモデルインスタンスを保存する必要があります。このエラーは、DjangoがケースインスタンスのIDを外部キーとして請求書モデルに保存できるようにすることができないため意味があります。 self.instance = form.save(commit=True)。そして、このリンクをチェックして、このエラーについての説明がDjango documentationにあることを確認してください。

1

ManyToMany関係による保存シーケンスに問題がある可能性があります。その優れた公式ドキュメントからリードを持っている最初の...

Every time you save a form using commit=False , Django adds a save_m2m() method to your ModelForm subclass. After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data.

例:

# Create a form instance with POST data. 
>>> f = AuthorForm(request.POST) 

# Create, but don't save the new author instance. 
>>> new_author = f.save(commit=False) 

# Modify the author in some way. 
>>> new_author.some_field = 'some_value' 

# Save the new instance. 
>>> new_author.save() 

# Now, save the many-to-many data for the form. 
>>> f.save_m2m() 

Here

で保存する方法の完全なドキュメントを読みます
関連する問題