Django - Как сохранить объекты модели в другой модели?
Допустим, у меня есть две модели (в файле models.py):
class FullName (models.Model):
firstName = models.CharField(max_length=30,null=True,blank=False,unique=True)
lastName = models.CharField(max_length=30,null=True,blank=False,unique=True)
class Address (models.Model):
addressLine = models.CharField(max_length=30,null=True,blank=False)
city = models.CharField(max_length=30,null=True,blank=False)
state = models.CharField(max_length=30,null=True,blank=False)
zipcode = models.CharField(max_length=30,null=True,blank=False)
Как я могу объединить эти две модели в новую модель? Таким образом, получается:
class FullName (models.Model):
firstName = models.CharField(max_length=30,null=True,blank=False,unique=True)
lastName = models.CharField(max_length=30,null=True,blank=False,unique=True)
class Address (models.Model):
addressLine = models.CharField(max_length=30,null=True,blank=False)
city = models.CharField(max_length=30,null=True,blank=False)
state = models.CharField(max_length=30,null=True,blank=False)
zipcode = models.CharField(max_length=30,null=True,blank=False)
class AllInformation (models.Model):
firstName = models.CharField(max_length=30,null=True,blank=False,unique=True)
lastName = models.CharField(max_length=30,null=True,blank=False,unique=True)
addressLine = models.CharField(max_length=30,null=True,blank=False)
city = models.CharField(max_length=30,null=True,blank=False)
state = models.CharField(max_length=30,null=True,blank=False)
zipcode = models.CharField(max_length=30,null=True,blank=False)
(all fields should be inherited from FullName and Address models)
PS: В моем файле views.py я вызвал метод сохранения следующим образом:
fullNameData = FullName(request.POST)
fullNameData.save()
and
AddressData = Address(request.POST)
AddressData.save()
Заранее спасибо, и я действительно ценю тех, кто отвечает на этот вопрос, потому что я вижу, что многие люди имеют ту же проблему. Я также взглянул на OneToOneField из документации django, но я ничего не понял, если честно xD
Возможно, лучше всего будет использовать One-To-One, это просто ForeignKey, чтобы не было дублирования данных в БД
Ваша модель будет выглядеть следующим образом
class AllInformation(models.Model):
fullname = models.OneToOneField(FullName, on_delete=models.CASCADE)
address = models.OneToOneField(Address, on_delete=models.CASCADE)
И тогда ваш метод сохранения в представлении будет выглядеть примерно так:
# save the full name
fullNameData = FullName(request.POST)
fullname = fullNameData.save()
# save the address
AddressData = Address(request.POST)
address = AddressData.save()
# create the information 'connector'
informationObj = AllInformation.objects.create(fullname=fullname, address=address)
# example uses
informationObj.fullname.firstName
informationObj.fullname.lastName
informationObj.address.city
Лично я бы просто объединил все три формы в одну, например:
forms.py
views.py
from django.shortcuts import render, redirect, get_object_or_404
# + import form & AllInformation
def informationFormView(request, pk=None):
# This being None = New Form
informationObj = None
if pk:
informationObj = get_object_or_404(AllInformation, pk=pk)
infoform = InformationForm(data=request.POST or None, instance=informationObj)
if request.method == 'POST':
if infoform.is_valid():
infoform.save()
redirect('success')
# on not valid it'll re-render the page with errors
data = {
'obj': informationObj
'form': infoform,
}
return render(request, 'informationForm.html', data)
urls.py
from django.urls import path
from . import views
urlpatterns = [
# Two URLs -> 1 View
path('informationform', views.informationFormView, name='informationFormView'),
path('informationform/<int:pk>', views.informationFormView, name='informationFormView'),
]
informationForm.html
- Базовая форма взята из Docs, изменено действие для обработки правок
<form action="{% if obj %}{% url 'informationFormView' pk=obj.pk %}{% else %}{% url 'informationFormView' %}{% endif %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
Решение:
При отправке формы FullName я просто делаю:
data = AllInformation(firstName = request.POST.get("firstname"), lastName = request.POST.get("lastname"))
data.save()
Затем во второй функции при отправке формы адреса я просто делаю:
AllInformation.objects.filter(firstName=the first name got from FullName Form).update(addressLine = value, city = value, ... )
Надеюсь, это поможет всем, кто пытается объединить две (или более) модели в одну другую модель, которая должна содержать все поля предыдущей модели.