Я знаю, что опаздываю на вечеринку, но вот моя ситуация и то, что я придумал, что может пригодиться кому-то еще в будущем.
У меня есть 4 встроенные модели, которым нужен зарегистрированный пользователь.
- 2 как поле типа
created_by
. (устанавливается один раз при создании)
- и 2 других в качестве поля типа
closed_by
. (устанавливается только при условии)
Я использовал ответ, предоставленный rafadev , и превратил его в простой миксин , который позволяет мне указывать имя поля пользователя в другом месте.
Общий набор форм в forms.py
from django.forms.models import BaseInlineFormSet
class SetCurrentUserFormset(forms.models.BaseInlineFormSet):
"""
This assume you're setting the 'request' and 'user_field' properties
before using this formset.
"""
def save_new(self, form, commit=True):
"""
This is called when a new instance is being created.
"""
obj = super(SetCurrentUserFormset, self).save_new(form, commit=False)
setattr(obj, self.user_field, self.request.user)
if commit:
obj.save()
return obj
def save_existing(self, form, instance, commit=True):
"""
This is called when updating an instance.
"""
obj = super(SetCurrentUserFormset, self).save_existing(form, instance, commit=False)
setattr(obj, self.user_field, self.request.user)
if commit:
obj.save()
return obj
Mixin класс в вашем admin.py
class SetCurrentUserFormsetMixin(object):
"""
Use a generic formset which populates the 'user_field' model field
with the currently logged in user.
"""
formset = SetCurrentUserFormset
user_field = "user" # default user field name, override this to fit your model
def get_formset(self, request, obj=None, **kwargs):
formset = super(SetCurrentUserFormsetMixin, self).get_formset(request, obj, **kwargs)
formset.request = request
formset.user_field = self.user_field
return formset
Как это использовать
class YourModelInline(SetCurrentUserFormsetMixin, admin.TabularInline):
model = YourModel
fields = ['description', 'closing_user', 'closing_date']
readonly_fields = ('closing_user', 'closing_date')
user_field = 'closing_user' # overriding only if necessary
Будьте осторожны ...
... так как этот смешанный код будет каждый раз устанавливать текущего пользователя, вошедшего в систему. Если вам нужно заполнить поле только при создании или при конкретном обновлении, вам нужно решить эту проблему в методе сохранения модели. Вот несколько примеров:
class UserOnlyOnCreationExampleModel(models.Model):
# your fields
created_by = # user field...
comment = ...
def save(self, *args, **kwargs):
if not self.id:
# on creation, let the user field populate
self.date = datetime.today().date()
super(UserOnlyOnCreationExampleModel, self).save(*args, **kwargs)
else:
# on update, remove the user field from the list
super(UserOnlyOnCreationExampleModel, self).save(update_fields=['comment',], *args, **kwargs)
Или если вам нужен только пользователь, если задано определенное поле (например, логическое поле closed
):
def save(self, *args, **kwargs):
if self.closed and self.closing_date is None:
self.closing_date = datetime.today().date()
# let the closing_user field set
elif not self.closed :
self.closing_date = None
self.closing_user = None # unset it otherwise
super(YourOtherModel, self).save(*args, **kwargs) # Call the "real" save() method.
Этот код, возможно, можно сделать более общим, так как я довольно новичок в python, но это то, что будет в моем проекте на данный момент.