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, ... )

Надеюсь, это поможет всем, кто пытается объединить две (или более) модели в одну другую модель, которая должна содержать все поля предыдущей модели.

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