2017-01-20 10 views
0

これはむしろ単純でなければならないもののようですが、必要な共通のものでなければなりませんが、django - 1つのフォームを使用して2つのモデルインスタンスを作成する

私は、イベントを必要とする複数の他のモデルにリンクされているイベントモデルを持っています。そのため、別のイベントモデルを作成しました。今、私はジョブモデルを作成するときにイベントを作成したいのですが、それを行う方法を理解するのに問題があります。

私の仕事フィールドには、イベントとのOneToOneFieldの関係があり、イベントを作成するときに決定する必要があるのは期間だけです。

単純化されたジョブのモデルは次のようになります。

class Job(models.Model): 
    customer = models.ForeignKey(Customer) 
    address = models.CharField(max_length=100, verbose_name="Job Address", null=False, blank=False) 
    city = models.CharField(max_length=100, verbose_name="City", null=True, blank=True) 
    state = models.CharField(max_length=2, verbose_name="State", null=True, blank=True) 
    zip = models.CharField(max_length=5, verbose_name="Zip Code", null=True, blank=True) 
    # Simply need to set duration 
    event = models.OneToOneField(Event, on_delete=models.CASCADE, null=False, blank=False) 

および簡体イベントモデルは次のようになります。

class Event(models.Model): 

    TIME_LIST = (
     (1, "0:30"), 
     (2, "1:00"), 
     (3, "1:30"), 
     (4, "2:00"), 
     (5, "2:30"), 
     (6, "3:00"), 
     (7, "3:30"), 
     (8, "4:00"), 
     (9, "4:30"), 
     (10, "5:00"), 
     (11, "5:30"), 
     (12, "6:00"), 
     (13, "6:30"), 
     (14, "7:00"), 
     (15, "7:30"), 
     (16, "8:00"), 
    ) 

    title = models.CharField(max_length=255) 
    employee = models.ForeignKey(Employee, null=True, blank=True) 
    start_time = models.DateTimeField(null=True, blank=True) 
    end_time = models.DateTimeField(null=True, blank=True) 
    range = RecurrenceField(null=True, blank=True) 
    duration = models.IntegerField(choices=TIME_LIST, null=True, blank=True) 
    is_all_day = models.BooleanField(default=False, null=False, blank=False) 

私は、ジェネリックCBVsを使用していますので、単に:

class JobCreate(CreateView): 
    template_name = 'jobs/create.html' 
    success_url = '/schedule/add/' 
    form_class = JobCreateForm 

    def get_success_url(self): 
     return self.success_url + str(self.object.id) 

私のフォームは次のように単純になります:

class JobCreateForm(forms.ModelForm): 
    class Meta: 
     model = Job 
     fields = [ 
      'customer', 
      'address', 
      'city', 
      'state', 
      'zip', 
     ] 

私が必要とするのは、自分のジョブフォーム内で期間を選択するボックスを作ってから、Eventの新しいインスタンスを作成し、そのjob_idを私のJobモデルのイベントフィールドに差し込み、一気に

私はinlineformset_factoryを見ました。私が必要としているように思えますが、エラーが続いているので、間違った考えか、間違っています。私は他の人が示唆しているカップルミックスインを試してみたところ、彼らは過度のように思えて、とにかく私のために働かなかった。

答えて

1

Eventの2番目のフォームを作成してテンプレートにレンダリングすることもできます。次に、あなたのビューでは、まずそれを保存してイベントを作成し、次にJobフォームを保存し、作成したばかりのイベントに関連イベントを設定します。

また、1つのフォームを希望する場合は、期間フィールドをジョブフォームに追加し、フォームのsave機能をオーバーライドすることもできます。あなたのケースであなたはそれがwouldn(それによってのみ作成単一の関連オブジェクトを作成するために、単一のフォームを必要とする)OneToOneFieldを使用しているように、この

def save(self, commit=True): 
    e = Event.objects.create(duration=self.cleaned_data.get('duration')) 

    job = super().save(commit=False) 
    job.event = e 
    job.save() 
    return job 

フォームセットは、複数のフォームを作るために実際にあるようなものを見ることができるのセーブ上書きそれらを使うのは意味がありません。

+0

ありがとうございました。それがそれでした。私はそれが単純でなければならないことを知っていた。 –

0

私が受けた答えは正確ではないことが分かりました。なんらかの理由(django magic)では、saveはデータを取得するために1回、保存するために1回以上呼び出されるため、ジョブが作成されるたびに2つのイベントインスタンスが作成されていました。別の問題は、ジョブを保存する前にイベントを保存する必要があること、またはjob.save()を実行しようとするとエラーがスローされることでした。私は次のコードを使用して解決しました。

def save(self, commit=True): 
    job = super(JobCreateForm, self).save(commit=False) 
    if commit: 
     event = Event(duration=self.cleaned_data.get('duration'), title=self.cleaned_data.get('customer')) 
     event.save() 
     job.event = event 
     job.save() 
    return job 
関連する問題