A package providing a multi-ModelForm solution for django
Project description
django-stapler
Provides a simple way to combine multiple ModelForm classes
Description
Django's ModelForm class lets you create a Form class for a model. This lets you conveniently create and update model instances. In some specific cases it would be desiarble to combine multiple ModelForms so that you can create and update multiple model instances in one view with one form. django-stapler provides this functionality
Dependencies
- Django 2.2+
Installing
pip install django-stapler
Basic usage
Add app to settings.py
INSTALLED_APPS = [ ...
'stapler',
]
Define Model classes as usual
models.py
from django.db import models
# Create your models here.
class Bike(models.Model):
name = models.CharField(max_length=10)
frame_type = models.CharField(max_length=10, blank=True, null=True)
class Manufacturer(models.Model):
name = models.CharField(max_length=10)
chief = models.CharField(max_length=10)
Also declare the ModelForm classes as usual, and in addition staple the ModelForms together by creating a new StapleForm class.
In the inner Meta class set the modelforms attribute to a tuple of to staple ModelForms.
forms.py
from django.forms import ModelForm
from stapler.forms import StaplerForm
from .models import Bike, Manufacturer
class BikeModelForm(ModelForm):
class Meta:
model = Bike
fields = ['name', 'price']
class ManufacturerModelForm(ModelForm):
class Meta:
model = Manufacturer
fields = ['name', 'revenue']
class StapledForm(StaplerForm):
class Meta:
modelforms = (BikeModelForm, ManufacturerModelForm)
#auto_prefix = False, defaults is True
The StapledForm yields a form with four fields: bike__name, bike__price, manufacturer__name, manufacturer__revenue.
If you want to keep the original field names, you can set the auto_prefix attribute in the Meta class to False.
This may lead to unexpected behaviour when fieldnames between models clash.
You can use the StapledForm in views.py to create a new Bike and Manufacturer instance in one go by calling
form.save(). This wil return a dictionary with keys resembling the Model class names in lowercase with the _instance
suffix. The keys map to the newly created instances:
views.py
from django.views.generic.edit import FormView
from .forms import StapledForm
class SomeView(FormView):
template_name = 'example.html'
form_class = StapledForm
success_url = '/thanks/'
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
result = form.save()
nw_bike = result['bike_instance'] # the saved bike instance
nw_manufacturer = result['manufacturer_instance'] # the saved manufacturer instance
return super().form_valid(form)
You can also use the form to update existing instances by providing a tuple of instances to the named instances argument:
from .models import Bike, Manufacturer
from .forms import StapledForm
...
# inside view function
bike = Bike.objects.first()
manufacturer = Manufacturer.objects.first()
form = StapledForm(data=request.POST, instances=(bike, manufacturer))
if form.is_valid():
result = form.save()
result # this is a dictionary with the updated instances
StapledForm provides the pre_save and post_save hooks. These methods
are called before and after the instances are saved when the save() method is called:
class StapledForm(StaplerForm):
...
def pre_save(self):
print("did you get the memo?")
def post_save(self):
print("have you seen my stapler?")
Extra options
In addition to modelforms attribute, you can set a few options in Meta class that alter the behaviour of the StaplerForm
auto_prefix: defaults toTrue. This will append a prefix of the model class name to the appropriate fieldsrequired: A tuple of theModelFormclasses that are required. By default, allModelFormclasses defined inmodelformsare required. If aModelFormis not in therequiredattribute, it's errors are ignored andis_valid()can still returnTrue. Callingsave()in this case will only save the instances ofModelFormsthat did validate. Instead of an instance,Noneis stored in the returned dictionary
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django-stapler-1.1.0.2.tar.gz.
File metadata
- Download URL: django-stapler-1.1.0.2.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.6.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
205ae62b9e84fe709fb13678ef72db8b9f3be6ea379101bcfda68a38ee7d367e
|
|
| MD5 |
e76a06b65c23a0c97ac252857bc2e1d3
|
|
| BLAKE2b-256 |
beec5e92f387964d9bf4c13e357a1d59dfc08a1deff4b50b681cdb891ffeb531
|
File details
Details for the file django_stapler-1.1.0.2-py3-none-any.whl.
File metadata
- Download URL: django_stapler-1.1.0.2-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.6.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0ba5153b23023c4a3c1a71d63c945aa32afdc8ba47ecdad55905e3faa18edce
|
|
| MD5 |
774fd1afc7a6a0684b9d32f4e248bd35
|
|
| BLAKE2b-256 |
0cb89888e9f72e57fd598e0980ee3bfcba1cf3a816c470f4cfda4818e656a44c
|