2👍
✅
The only solution I can think off is queuing the operations and perform them when you call save()
.
class PostponedOpMixin(models.Model):
def __init__(self, *args, **kwargs):
self._postponed_ops = []
super(PostponedOpMixin, self).__init__(*args, **kwargs)
def _getattr(self, attr):
result = self
for part in attr.split('.'):
result = getattr(result, part)
return result
def postpone(self, op, *args, **kwargs):
if self.pk: # execute now if self already has a pk
return self._getattr(op)(*args, **kwargs)
self._postponed_ops.append((op, *args, **kwargs))
def save(self, *args, *kwargs):
super(PostponedOpMixin, self).save(*args, **kwargs)
while self._postponed_ops:
op, args, kwargs = self._postponed_ops.pop(0):
self._getattr(op)(*args, **kwargs)
def Meta:
abstract = True
This way you can do:
class Book(PostponedOpMixin):
...
authors = models.ManyToManyField(Author)
...
instance = Book()
instance.title = "Romeo and Juliet"
instance.postpone('authors.add', shakespeare)
...
# and some time later:
instance.save()
This code is untested and intended as a start point. Any bug is left as an exercise for the reader.
2👍
Maybe you could postpone the actual book’s authors adding to the moment you are sure you want to save that book into the database.
In the meantime, you could store a list of processed (but not yet saved) author objects for each book object.
class Book(models.Model):
title = models.CharField(max_length=128)
pages = models.PositiveIntegerField()
authors = models.ManyToManyField(Author)
@classmethod
@transaction.atomic
def create(cls, data):
try:
b = cls(title=data["title"],
pages=data["pages"])
b.author_list = list()
for a in data["authors"]:
b.authors_list.append(Author.create(a))
return b
except Exception:
# ...
raise
Then, when you are sure you want to save the object, you have to save all the authors in that list, and then add them to the ‘authors’ field in the corresponding book object.
- [Django]-Avoid concurrent access to same queue element
- [Django]-Fixture inheritance in django TestCase
- [Django]-Intermittent ImportError with Django package
- [Django]-Django model formset factory and forms
- [Django]-Sprinkling VueJs components into Django templates
Source:stackexchange.com