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.
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
- Create the “base” row (
ArkiObject
) on page #1. - 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.