I have the models AppVersion, App & DeployApp. In the AppVersion model users can upload APK files to the filesystem. I am using a pre_save signal to prevent uploading APK files with the same version_code for a specific App like this:
@receiver(pre_save, sender=AppVersion) def prevent_duplicate_version_code(sender, instance, **kwargs): qs = AppVersion.objects.filter(app_uuid=instance.app_uuid, version_code=instance.version_code) if qs.exists(): raise FileExistsError("Version code has to be unique for a specific app") This signal does what I want, except it also raises the error when I am trying to create an object in the bridge-table DeployApp.
# models.py class App(models.Model): app_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True) app_name = models.CharField(max_length=100) class AppVersion(models.Model): app_version_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True) app_uuid = models.ForeignKey(App, on_delete=models.CASCADE, related_name='app_versions') app_version_name = models.CharField(max_length=100) version_code = models.IntegerField(blank=True, null=True, editable=False) source = models.FileField(upload_to=get_app_path, storage=AppVersionSystemStorage()) class DeployApp(models.Model): deploy_app_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True) app_version = models.ForeignKey(AppVersion, on_delete=models.CASCADE) device_group = models.ForeignKey(DeviceGroup, on_delete=models.CASCADE) release_date = UnixDateTimeField() My guess is that when creating an object of DeployApp the related AppVersion is also saved and thus the pre_save signal is called and raises the Exception.
I also tried to override the save() method for the AppVersion model but the results are the same.
How do I make sure that the Exception only happens upon creating a new AppVersion instance and does not happen when adding or editing a DeployApp instance?
UniqueConstraint. condition. A Q object that specifies the condition you want the constraint to enforce. For example: UniqueConstraint(fields=['user'], condition=Q(status='DRAFT'), name='unique_draft_user')
unique_together may be deprecated in the future. This is a list of lists that must be unique when considered together. It's used in the Django admin and is enforced at the database level (i.e., the appropriate UNIQUE statements are included in the CREATE TABLE statement).
To add composite primary key in Python Django, we can set the unique_together field in the Meta class in the model class. to set unique_together to (('key1', 'key2'),) to make key1 and key2 part of the composite primary key.
If you'd like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you've explicitly set Field.primary_key , it won't add the automatic id column. Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
Solved it thanks to Bear Brown his suggestion. I removed the signal and added UniqueConstraint to the AppVersion model like this:
class Meta: db_table = 'app_version' constraints = [ models.UniqueConstraint(fields=['app_uuid', 'version_code'], name='unique appversion') ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With