how to add a different model form to modelformset_factory

  • Last Update :
  • Techknowledgy :

models.py

class Project(models.Model):
   description = models.CharField(max_length = 50, blank = True, null = True)
status = models.IntegerField(choices = STATUS_CHOICES,
   default = 4)
owner = models.ForeignKey(staff, on_delete = models.CASCADE, blank = True, null = True)
   ...

   class Update(models.Model):
   project = models.ForeignKey(Project, on_delete = models.CASCADE)
notes = models.CharField(max_length = 50, blank = True, null = True)
update_date = models.DateTimeField(
   default = timezone.now, editable = False)
added_by = models.CharField(max_length = 35, blank = True)

forms.py

class CreateUpdateForm(ModelForm):
   class Meta:
   model = Update
fields = ('notes')

class EditProjectForm(ModelForm)
class Meta:
   model = Project
fields = ('__all__')

views.py

def mds_projects(request):
   project_formset = modelformset_factory(Project, form = EditProjectForm, extra = 0)

if request.method == 'POST':
   formset = project_formset(request.POST, request.FILES)
if formset.is_valid():
   for f in formset:
   project = f.save(commit = False)

update_form = CreateUpdateForm(request.POST, request.FILES)
if update_form.is_valid():
   update = update_form.save(commit = False)
update.project = project
project.save()
update.save()
else:
   print(update_form.errors)
return redirect('MDS_Projects')
else:
   print(formset.errors)
else:
   projects = Project.objects.filter(dept = 'Assistive Technology')
formset = project_formset(queryset = projects)
update_form = updateForm()
return render(request, 'MDSprojectsB.html', {
   'formset': formset,
   'update_form': update_form
})

Suggestion : 2

ModelForm is a regular Form which can automatically generate certain fields. The fields that are automatically generated depend on the content of the Meta class and on which fields have already been defined declaratively. Basically, ModelForm will only generate fields that are missing from the form, or in other words, fields that weren’t defined declaratively.,Fields defined declaratively are left as-is, therefore any customizations made to Meta attributes such as widgets, labels, help_texts, or error_messages are ignored; these only apply to fields that are generated automatically.,The generated Form class will have a form field for every model field specified, in the order specified in the fields attribute.,You can only use this technique to opt out from a field defined declaratively by a parent class; it won’t prevent the ModelForm metaclass from generating a default field. To opt-out from default fields, see Selecting the fields to use.

>>> from django.forms
import ModelForm
   >>>
   from myapp.models
import Article

# Create the form class. >>>
class ArticleForm(ModelForm):
   ...class Meta:
   ...model = Article
   ...fields = ['pub_date', 'headline', 'content', 'reporter']

# Creating a form to add an article. >>>
   form = ArticleForm()

# Creating a form to change an existing article. >>>
   article = Article.objects.get(pk = 1) >>>
   form = ArticleForm(instance = article)
from django.db
import models
from django.forms
import ModelForm

TITLE_CHOICES = [
   ('MR', 'Mr.'),
   ('MRS', 'Mrs.'),
   ('MS', 'Ms.'),
]

class Author(models.Model):
   name = models.CharField(max_length = 100)
title = models.CharField(max_length = 3, choices = TITLE_CHOICES)
birth_date = models.DateField(blank = True, null = True)

def __str__(self):
   return self.name

class Book(models.Model):
   name = models.CharField(max_length = 100)
authors = models.ManyToManyField(Author)

class AuthorForm(ModelForm):
   class Meta:
   model = Author
fields = ['name', 'title', 'birth_date']

class BookForm(ModelForm):
   class Meta:
   model = Book
fields = ['name', 'authors']
from django
import forms

class AuthorForm(forms.Form):
   name = forms.CharField(max_length = 100)
title = forms.CharField(
   max_length = 3,
   widget = forms.Select(choices = TITLE_CHOICES),
)
birth_date = forms.DateField(required = False)

class BookForm(forms.Form):
   name = forms.CharField(max_length = 100)
authors = forms.ModelMultipleChoiceField(queryset = Author.objects.all())
from django.core.exceptions
import NON_FIELD_ERRORS
from django.forms
import ModelForm

class ArticleForm(ModelForm):
   class Meta:
   error_messages = {
      NON_FIELD_ERRORS: {
         'unique_together': "%(model_name)s's %(field_labels)s are not unique.",
      }
   }
>>> from myapp.models
import Article
   >>>
   from myapp.forms
import ArticleForm

# Create a form instance from POST data. >>>
   f = ArticleForm(request.POST)

# Save a new Article object from the form 's data. >>>
   new_article = f.save()

# Create a form to edit an existing Article, but use
# POST data to populate the form. >>>
   a = Article.objects.get(pk = 1) >>>
   f = ArticleForm(request.POST, instance = a) >>>
   f.save()
# Create a form instance with POST data. >>>
   f = AuthorForm(request.POST)

# Create, but don 't save the new author instance. >>>
   new_author = f.save(commit = False)

# Modify the author in some way. >>>
   new_author.some_field = 'some_value'

# Save the new instance. >>>
   new_author.save()

# Now, save the many - to - many data
for the form. >>>
   f.save_m2m()

Suggestion : 3

Last Updated : 09 Jan, 2020

1._
class GeeksModel(models.Model):
   title = models.CharField(max_length = 200)
description = models.TextField()

Now if one wants to create a modelformset for this model, modelformset_factory needs to be used. A formset is a layer of abstraction to work with multiple forms on the same page. It can be best compared to a data grid.

from django.forms
import formset_factory
GeeksFormSet = modelformset_factory(GeeksModel)

Let’s explain what exactly is happening, left side denotes the name of the field and to right of it, you define various functionalities of an input field correspondingly. A field’s syntax is denoted as
Syntax :

Field_name = models.FieldType(attributes)

Let’s explain what exactly is happening, left side denotes the name of the field and to right of it, you define various functionalities of an input field correspondingly. A field’s syntax is denoted as
Syntax :

Field_name = models.FieldType(attributes)

Suggestion : 4

modelformset_factory() requires the first argument be the model the formset is for. After specifying the model, different optional arguments can be specified. We'll use two optional arguments - fields and extra.,Once we have created the formset instance, we call render_to_response with the argument being a dictionary that has the formset assigned to the bird_formset key.,Formsets can be created for different types of forms, including model forms. Since we want to create new instances of the Bird model, a model formset is a natural fit.,The model form requires we specify the model we want the form to be associated with and the fields we want to include in the form.

The app will only have one model, Bird, that stores information about each bird we've seen.

# models.py
from django.db
import models

class Bird(models.Model):
   common_name = models.CharField(max_length = 250)
scientific_name = models.CharField(max_length = 250)

def __str__(self):
   return self.common_name

We will manage URLs with a project level urls.py file set to include the app level urls.py file.

# project level urls.py
from django.contrib
import admin
from django.urls
import path, include

urlpatterns = [
   path('admin/', admin.site.urls),
   path('', include('birds.urls')),
]

The app level urls.py will include the paths to the two pages of the app.

# app level urls.py
from django.urls
import path
from.views
import BirdAddView, BirdListView

urlpatterns = [
   path('add', BirdAddView.as_view(), name = "add_bird"),
   path('', BirdListView.as_view(), name = "bird_list")
]

If we just wanted to add a single model form to our page, we would create it like this:

# forms.py
from django.forms
import ModelForm
from.models
import Bird

# A regular form, not a formset
class BirdForm(ModelForm):
   class Meta:
   model = Bird
fields = [common_name, scientific_name]

To create a model formset, we don't need to define the model form at all. Instead, we use Django's modelformset_factory() which returns a formset class for a given model.

# forms.py
from django.forms
import modelformset_factory
from.models
import Bird

BirdFormSet = modelformset_factory(
   Bird, fields = ("common_name", "scientific_name"), extra = 1
)

Suggestion : 5

In order to use ModelFormSet, Django makes use of modelformset_factory.,In Django, ModelFormsets is an advanced way to handle multiple forms created with a model. ModelFormSets uses the model to create model instances.,Just as standard Django forms can be grouped together as a set in a Django FormSet, Django model forms can be grouped into a ModelFormSet. ModelFormSet also has a lot of similarities with the standard FormSet.,The example below demonstrates how ModelFormSet can be used.

Installation

pip install pipenv
pipenv shell
pipenv install django

Then:

django - admin startproject DjangoFormset. /
django-admin startproject DjangoFormset ./
python manage.py startapp codebase
python manage.py migrate
python manage.py runserver
INSTALLED_APPS = [
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',

   'codebase'
]
from django.db
import models

# adding the model
class ModelFormSetModel(models.Model):
   name = models.CharField(max_length = 200)
email = models.CharField(max_length = 200)
department = models.TextField()

# the name of the model that will be showing in the admin panel
class Meta:
   verbose_name_plural = 'data'

#so it will use emaill to reference a particular data
def __str__(self):
   return self.email

For example:

from.models
import ModelFormsetModel
from django.forms
import modelformset_factory

DjangoFormset = modelformset_factory(ModelFormsetModel, fields = '__all__')
from django.shortcuts
import render

#importing the model
from.models
import ModelFormSetModel

# importing django modelformset_factory used
for modelformset
from django.forms
import modelformset_factory

def home(request):
   #displaying the neccessary fields needed to be displayed on the frontend
DjangoFormSet = modelformset_factory(ModelFormSetModel, fields = ['name', 'email', 'department'])
# refrencing the DjangoFormset as a method
formset = DjangoFormSet()

# Add the formset to context dictionary
context = {
   'formset': formset
}

return render(request, "app/home.html", context)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Django ModelFormSets</title>
</head>
<body>   
    <form method="POST" enctype="multipart/form-data">
        <!-- csrf token  -->
        {% csrf_token %}
        <!-- displaying the form from the backend -->
        {{ formset.as_p }}
        <input type="submit" value="Submit">
    </form>
</body>
</html>