Update two or more models at same time with UpdateView - django

Is there some way to update two or more models at the same time with UpdateView? For example having this:
class PEEncargadoView(UpdateModelMixin,UpdateView):
model = Encargado
form_class = FormEncargado
success_url = '/'
template_name = 'productores/PE/encargado.html'
Update other models besides of Encargado but in this same view
I know that this could be possible overriding get_context_data, but exactly how? if I don't need to pass any variables to the template.

you can't do it with UpdateModelMixin - it's designed for working with a single model.
This question shows how to work with multiple forms in CBV: Django: Can class-based views accept two forms at a time?.
Django has formsets https://docs.djangoproject.com/en/1.8/topics/forms/formsets/ which can be used together with ModelForm to allow edition of multiple models on one page.

Related

Two model in one UpdateView "Django"

my views :
from .models import Settings, SocialMediaSetting
class UpdateSocialMediaSetting(LoginRequiredMixin, UpdateView):
model = SocialMediaSetting
fields = '__all__'
template_name = "staff/settings/social-media-settings-update.html"
class UpdateSettings(LoginRequiredMixin, UpdateView):
model = Settings
fields = '__all__'
template_name = "staff/settings/settings-update.html"
two different class in models without any relation, I want show both in one html and one form both models has just one object
you'll need to ditch the UpdateView, but this way won't take long to implement
Use a TemplateView (at least you won't have to change your other mixin)
Create two ModelForms
override the get_context_data() to pass the forms to the template
when forms are submitted, override the post() method to save them yourself
mchesler613 wrote an awesome article explaining how to do this here.
(make sure to give him a star)

How to update multiple rows at once using Django forms.ModelForm in views.py

I am trying to update many rows of a model based on user input but I'm having trouble updating them in views.py.
I create the modelForm
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ["book_title", "book_title_2"]
In my views
def my_view(request):
query = MyModel.objects.filter(foo=foo)
forms = [MyForm(instance=q) for q in query]
context["forms"] = forms
In templates I iterate over forms and input data for some rows. I know normally on form submission I can use form = MyForm(request.POST) and use the is_valid() and save() attributes to save new data to my model. But when I am using a list of forms like above to update many instances, how can I actually save the forms in views.py? When I call MyForm(request.POST) after submitting all of the queried forms at once I get this error 'WSGIRequest' object has no attribute 'FORM' . When I look at the post data I see a list values for book_title and book_title_2. It seems that because I'm submitting more than one form it doesn't work. Is there a workaround for this? Thanks
As posted in the comments by Willem Formsets is exactly what is needed to handle multiple form in views. In my case specifically where I am making multiple forms based on a model and a queryset of that model, modelformset_factory worked

Django model form cant use two modelforms

I was wondering how i can use two models in a modelform
I tried :
from django import forms
from .models import Question, Choice
class CreateQuestionForm(forms.ModelForm):
class Meta:
model = question, choice
Fields = [
'question'
'choice_text
]
You have to use formsets in order to use two different forms in the same.
Firstly, you have to define each form from their models.
Then, you can use formset_factory to combine both forms.

Create multiple objects in django admin at once

For example, I have a Post model:
Class Post(models.Model):
title = models.Charfield(max_length=200)
# other fields
I wonder is there a way to create multiple posts at once in admin. In other words, I need a formset instead of single form on post creation page.
I've heard recently about a django app that exactly does this job. It's called django-bulk-admin and enables bulk add/update in the admin.
Possibly, the best way to do exactly what you want is extend the ModelAdmin class, because it has no formsets on it, except for those used on InlineFormsets.
After that you could customize the admin change_form template, to include your formsets
The quick-and-dirty way to do it using admin is wrap your Post model as an inline formset of another modeladmin and add the extra option to it.

create model formsets from same model but with different model forms

I have an Image model in my Django project. Because of different types of Image I have created three ModelForms according to each type:
class Xray(ModelForm):
#extra_field: Choice Field with specific options for Xray
class Meta:
model = Image
class Internal(ModelForm):
#extra_field: Choice Field with specific options for Internal
class Meta:
model = Image
class External(ModelForm):
#extra_field: Choice Field with specific options for External
class Meta:
model = Image
Each ModelForm has a save logic implemented. I want to create a model formset one for each Image type but want to use the correct ModelForm for each type of Image. I won't use this formset for editing thus I always want it to be empty and have 5 forms(5 items). I can't seem to find in django docs where i can use a specific form for a formset. Only a specific formset (inherit from BaseModelFormSet)
Is it possible to use specific form for each model_formset?
You can do the following:
from django.forms.models import modelformset_factory
from someproject.someapp.models import Image
from someproject.someapp.forms import Internal
ImageFormSet = modelformset_factory(Image, form=Internal)
Here are the docs for modelform_factory, which don't mention the form argument. However, in the "Note" below the examples therein that the function delegates to formset_factory, which is documented to take the form argument. It's just a minor docs issue, and might be a good reason to create a fork of Django, make an update to the docs, and create a pull request.