Использовать две модели в одном представлении, которое можно сохранять и редактировать в django
Любители нуля и единицы. Как сделать так, чтобы в представлении было две формы с двумя разными моделями, но сохранение одной формы не влияло на другую?
пытаюсь использовать модельформ использовать его в одном представлении. но я хотел бы знать, как это решить или лучшую практику для таких случаев.
Вы можете использовать атрибут name для кнопки на форме. Например;
<form>
...
<input type="submit" name="save-user" value="Save user" />
</form>
<form>
...
<input type="submit" name="save-category" value="Save category" />
</form>
Тогда в python вы можете определить, какая кнопка была нажата, следующим образом;
if 'save-user' in request.POST:
# save the user
elif 'save-category' in request.POST:
# save the category
Итак, вы хотите отобразить две разные формы в шаблоне и сохранить их по отдельности в базе данных.
Для себя я обычно придерживаюсь самого простого способа и лучшего для меня на данный момент.
Вот он, возьмем этот в качестве примера
def update_profile(request):
if request.method == 'POST':
user_form = UserForm(request.POST, instance=request.user)
profile_form = ProfileForm(request.POST, instance=request.user.profile)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
# redirect to somewhere else
else:
# message.error
user_form = UserForm(instance=request.user)
profile_form = ProfileForm(instance=request.user.profile)
return render(request, 'profiles/profile.html', {
'user_form': user_form,
'profile_form': profile_form
})
Django очень умно обращается с ModelForms, после выполнения ряда закулисных проверок, когда
form.is_valid()
Вызывается.
В результате будут сохранены поля, которые были изменены, и исключены те, в которых изменений не было.
Вот шаблонный рендеринг форм
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<button type="submit">Save changes</button>
</form>
А вот и формы.о
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('url', 'location', 'company')
Как я уже говорил, Django достаточно умен, чтобы обрабатывать ваши ModelForms, пока вы вызываете form.is_valid(), он будет делать все за вас.
Для меня это был более легкий подход
Если вам нужно что-то более контролируемое Посмотрите Django Formset
создайте две Модели и используйте их в ModelForm:
class UserUpdateForm(ModelForm):
class Meta:
model = User
fields = ["username", "email", "phone_number", "bioghraphy", "avatar"]
class AddressForm(ModelForm):
class Meta:
model = Address
fields = "__all__"
в файле views.py:
class AccountFormView(TemplateView):
...
def post(self, request, *args, **kwargs):
user_form = UserUpdateForm(
request.POST, prefix="user", instance=self.get_object()
)
address_form = AddressForm(
request.POST, prefix="address", instance=self.get_object_address()
)
if user_form.is_valid():
user_form.save()
return HttpResponseRedirect(
reverse_lazy(
"neeko.apps.accounts:accounts-landing",
kwargs={"pk": self.get_object().pk},
)
)
if address_form.is_valid():
address_form.save()
return HttpResponseRedirect(
reverse_lazy(
"neeko.apps.accounts:accounts-landing",
kwargs={"pk": self.get_object().pk},
)
)
return self.render_to_response(
self.get_context_data(user_form=user_form, address_form=address_form)
)
Шаблон:
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
<button type="submit">form 1</button>
</form>
<h1>form segin</h1>
<form method="post">
{% csrf_token %}
{{ address_form.as_p }}
<button type="submit">form 2 </button>
</form>
example
https://gist.github.com/josuedjh3/7ea29c70a0167ff34a1216edb5dbed05
