I have a m2m relationship between Servers
and Products
in Django with a through table called ServerProducts
.
class ServerProduct(TimeStampedModel):
# Additional fields may be required in the future
server = models.ForeignKey('Server', on_delete=models.CASCADE)
product = models.ForeignKey('Product', on_delete=models.CASCADE)
class Server(TimeStampedModel):
name = models.CharField(max_length=35)
# ...
products = models.ManyToManyField('Product', through='ServerProduct',
related_name='products', blank=True)
class Product(TimeStampedModel):
name = models.CharField(max_length=45, unique=True)
# ...
servers = models.ManyToManyField(
'Server', through='ServerProduct', related_name='servers')
In my view I have a form which allows users to create a Server and select from a list of all products for the Server to be associted with.
In order to create the ServerProduct
objects (for the through table) on each save I have to write the following code inside save()
.
class ServerForm(forms.ModelForm):
class Meta:
model = Server
fields = '__all__'
def save(self, commit=True):
instance = super(ServerForm, self).save(commit=False)
instance.save()
if instance.products.count():
instance.products.clear()
for product in self.cleaned_data['products']:
ServerProduct.objects.create(server=instance, product=product)
return instance
I want to be able to reuse the form for both Create
and Update
views. Hence why I have to check if the current Server is associated with any products, and then do instance.products.clear()
. To make sure it removes any previous products if they get deselected by a user.
This entire process feels unecessary, especially when I've read a lot about Django's built-in form.save_m2m()
method. My question is, is there a simpler way do achieve what I'm doing using Django built-in's?