How can I fill in related models separately through forms (OneToOneField)?

I have two table models. I write data to one of them using a form.

I also want to write data to the other model table using a form.

But I'm trying to link these tables.

Use the first one as a base.

And fill in their two tables in two stages. In the first stage, I write the first model.

In the second stage, the second model.

It is important for me to be able to select a field from the first model in order to display it when filling out the second form.

But I can't do it. I want both tables to have the same size by row when filling out.

In the future, I plan to add new models and forms - as well as the second form using a field from the first model.

What can I do? I take OneToOneField as a link.

What can I do to link the models but write data to them not in one form, in one template. But in different ones in two forms and in two templates.

When filling out a form as shown in the screenshot, I would like to display a drop-down list according to different conditions, but I get some kind of incomprehensible object, and not the contents of the field in the model.

enter image description here

How can I fill in related models separately through forms (OneToOneField)?

from django.db import models

# Create your models here.


class ArkiObject (models.Model):
    nameobject = models.TextField(verbose_name="Наименование объекта")

TYPE_OBJECT = [
    ("1", "Котельная"),
    ("2", "Сети"),
    ("3", "БМК"),
    ("4", "ЦТП"),
    ("5", "ТГУ"),
]

TYPE_WORK = [
    ("1", "Реконструкция"),
    ("2", "Капитальный ремонт"),
    ("3", "Строительство"),
]

TYPE_CITY = [
    ("1", "Бронницы"),
    ("2", "Луховицы"),
    ("3", "Павловский Посад"),
    ("4", "Раменское"),
    ("5", "Шатура"),
]

class ArkiOneObject (models.Model):
    city = models.CharField(
        choices=TYPE_CITY,
    verbose_name="Выберите ОМСУ")
    typeobject = models.CharField(
        choices=TYPE_OBJECT,
    verbose_name="Выберите тип объекта")
    typework = models.CharField(
        choices=TYPE_WORK,
    verbose_name="Выберите тип работ")
    nameobject = models.OneToOneField(ArkiObject, verbose_name="Наименование объекта", on_delete=models.CASCADE)

    
class ArkiTwoObject (models.Model):
    nameobject = models.OneToOneField(ArkiObject, verbose_name="Наименование объекта", on_delete=models.CASCADE)
    power_lenth = models.FloatField(verbose_name="Мощность или длина")
    potr_msd = models.IntegerField(verbose_name="Кол-во Потребители МСД")
    potr_cityzen = models.IntegerField(verbose_name="Кол-во Жители")
    potr_social = models.IntegerField(verbose_name="Кол-во Социальные")
    value_budget = models.FloatField(verbose_name="Объём финансирования")
    podryadchik = models.CharField(verbose_name="Подрядчик")
    date_contract = models.DateField(verbose_name="Дата заключения контракта")
    zena_contr = models.FloatField(verbose_name="Цена контракта")  
    

from django import forms
from .models import *


class FormOne (forms.ModelForm):
    class Meta:
        model = ArkiOneObject
        fields = "__all__"



class FormTwo (forms.ModelForm):
    class Meta:
        model = ArkiTwoObject
        fields = "__all__"
                

class FormThree (forms.ModelForm):
    class Meta:
        model = ArkiObject
        fields = "__all__"
                                

from django.shortcuts import render, redirect
from django.template import context
from django.http import HttpResponse
from .models import *
from .forms import *

def index(request):
    context={}

    return render(request, 'index.html', context)



def formone(request):
    context = {}
    formone = FormOne(request.POST or None)
    if formone.is_valid():
        formone.save()

        return redirect("formone")
    context['formone'] = formone
    return render(request, "formone.html", context)


def formtwo(request):
    context = {}
    formtwo = FormTwo(request.POST or None)
    if formtwo.is_valid():
        formtwo.save()

        return redirect("formtwo")
    context['formtwo'] = formtwo
    return render(request, "formtwo.html", context)    


def formthree(request):
    context = {}
    formthree = FormThree(request.POST or None)
    if formthree.is_valid():
        formthree.save()

        return redirect("formthree")
    context['formthree'] = formthree
    return render(request, "formthree.html", context)    

The “ArkiObject object (1)” text in the dropdown is Django’s default string for a model that lacks a __str__ method. Add one to every model you want to show in a <select>:

class ArkiObject(models.Model):
    ...
    def __str__(self):
        return self.nameobject

That alone makes the list display the nameobject value, instead of the object string.


Two-step workflow

  1. Create the “base” row (ArkiObject) on page #1.
  2. Redirect to page #2 and save form #2 with:
obj = form.save(commit=False)
obj.nameobject = base
obj.save()

Exactly the same pattern works for page #3, #4, … if you add more related models later.

Вернуться на верх