簡體   English   中英

django-使用一種形式創建兩個模型實例

[英]django - Using one form to create two model instances

這似乎應該很簡單,並且應該是常見的事情,但是我嘗試找到答案的次數越多,我就越困惑。

我有一個事件模型,該模型鏈接到需要事件的多個其他模型,因此為它創建了一個單獨的事件模型。 現在,我想在創建工作模型時創建一個事件,但是我很難弄清楚該如何做。

在我的工作領域中,我與一個事件具有OneToOneField關系,而在制作事件時我唯一需要確定的就是持續時間。

簡化的Job模型可能如下所示:

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)

我正在使用通用CBV,因此很簡單:

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的新實例,將ev​​ent_id插入Job模型的event字段中,然后一次性提交所有內容。

我查看了inlineformset_factory ,它似乎應該是我所需要的,並且不斷出錯,因此這是錯誤的主意,或者我使用的是錯誤的。 我嘗試了其他人建議的幾個混合器,它們看起來像是過分殺了,無論如何對我沒有用。

您可以為Event創建第二個表單並將其呈現在模板中。 然后,在您的視圖中,您可以先保存它,創建一個事件,然后保存您的Job表單並將其相關事件設置為剛剛創建的事件。

另外(我可能會這樣做),如果您希望使用一個表單,則可以將工期字段添加到工作表單中並覆蓋表單的save功能。 覆蓋的保存可能看起來像這樣

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

表單集實際上是用於創建多個表單的,因此在您的情況下,當您使用OneToOneField (從而僅創建需要單個表單來創建單個相關對象的表單)時,就沒有意義了。

我只是意識到我接受的答案並不完全正確。 由於某種原因(django魔術),保存被多次調用,一次用於獲取數據,一次被保存,因此每次創建作業時它都會創建兩個事件實例。 另一個問題是在保存作業或嘗試運行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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM