Ввод данных в Django с помощью отношений, какой способ является стандартным или наиболее эффективным?
В случае модели без отношений the, наиболее эффективным способом ввода данных будет использование django.forms.ModelForm. Возьмем следующий пример:
class Customer(models.Model):
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class CustomerModelForm(forms.ModelForm):
class Meta:
fields = ("first_name", "last_name")
model = Customer
form = CustomerModelForm(data={"first_name": "Jon", "last_name": "Doe"})
if form.is_valid():
form.save()
Но когда вы добавляете отношения, что является наиболее эффективным или лучшим стандартом. Давайте обновим модель до:
class Customer(models.Model):
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
address = models.ForeignKey(
"Address",
on_delete=models.PROTECT
)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class Address(models.Model):
street = models.CharField(max_length=120)
city = models.CharField(max_length=120)
state = models.CharField(max_length=2)
zip_code = models.CharField(max_length=5)
def __str__(self):
return f"{self.street}, {self.city}, {self.state} {self.zip_code}"
Одним из решений может быть следующее:
class CustomerModelForm(forms.ModelForm):
class Meta:
fields = ("first_name", "last_name", "address")
model = Customer
class AddressModelForm(forms.ModelForm):
class Meta:
fields = (
"street",
"city",
"state",
"zip_code"
)
model = Address
class Customer(forms.Form):
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
street = models.CharField(max_length=120)
city = models.CharField(max_length=120)
state = models.CharField(max_length=2)
zip_code = models.CharField(max_length=5)
def save(self):
address_form = AddressModelForm(
data={
"street": "123 Sycamore St",
"city": "Eagles Harbor",
"state": "AD",
"zip_code": "12345"
}
)
if address_form.is_valid():
address = address_form.save()
customer_form = CustomerModelForm(
data={"first_name": "Jon", "last_name": "Doe"}
)
if customer_form.is_valid():
return customer_form.save()
Или же вы полностью пропустите модельные формы:
class Customer(forms.Form):
...
def save(self):
address, c = Address.objects.get_or_create(
street="123 Sycamore St",
city="Eagles Harbor",
state="AD",
zip_code="12345"
)
customer, c = Customer.objects.get_or_create(
first_name="Jon",
last_name="Doe",
address=address,
)
return customer
Не уверен, что понимаю вас, но вижу, что вы делаете, я бы сделал это довольно просто:
class Customer(models.Model):
first_name=..
...
zip_code=..
class CustomerForm(forms.ModelForm):
class Meta:
fields = ('__ALL__')
model = Customer
При использовании ORM помогает представить, что происходит на уровне базы данных. Не совсем понятно, зачем создавать целую новую таблицу только для адресов.
Edit: Вы все еще можете сделать это так, и иметь address = models.ForeignKey(Address)
на вашей модели Customer
. Я думаю, что вы превращаете довольно простую вещь в нечто более сложное, чем она есть на самом деле. Вы также жестко кодируете значения, в этом нет необходимости.