Reputation: 151
I have a model mixin that sets created_at
, created_by
, updated_at
and updated_by
which I then inherit to most of the models in my project. This model mixin works fine. Obviously setting created_at
and modified_at
is very easy due to auto_now_add
and auto_now
.
class Timestampable(models.Model):
created_at = models.DateTimeField(
auto_now_add=True,
db_index=True,
verbose_name=_('created at')
)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name="created%(app_label)s_%(class)s_related", on_delete=models.SET_NULL)
updated_at = models.DateTimeField(
auto_now=True,
db_index=True,
verbose_name=_('updated at')
)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name="updated%(app_label)s_%(class)s_related", on_delete=models.SET_NULL)
class Meta:
abstract = True
ordering = ['-created_at']
But, what I want is to also create a mixin (or maybe subclass) CreateView
and UpdateView
to set created_by
and updated_by
to be self.request.user
everywhere those CBVs are used ( I would guess by modifying get_form()
or form_valid()
). I'll also need to create a similar admin mixin to modify save_model()
.
I have never created a custom mixin and the things I have found/tried aren't working. For example I got subclassing CreateView working by modifying get_form()
but then, I couldn't further modify get_form()
in the various class ModelXCreate(...)
views I created.
Does anybody know how I can achieve this? It'd be super useful to be able to have such a mixin and keep things DRY.
Upvotes: 2
Views: 697
Reputation: 477513
You can override the form_valid
method and thus work with:
from django.contrib.auth.mixins import LoginRequiredMixin
class CreateUpdateMixin(LoginRequiredMixin):
def form_valid(self, form):
instance = form.instance
if instance.pk is None: # created
instance.created_by = instance.updated_by = self.request.user
else: # updated
instance.updated_by = self.request.user
return super().form_valid(form)
Then we can use this mixin for our CreateView
/UpdateView
:
class MyCreateView(CreateUpdateMixin, CreateView):
# …
pass
class MyUpdateView(CreateUpdateMixin, UpdateView):
# …
pass
Upvotes: 1