Django, добавление исключенных свойств к представленной модели
У меня есть модель, и я исключил два поля, поля create_date
и created_by
. Теперь я получаю ошибку "Not Null" при использовании метода save()
, потому что created_by
пуст.
Я попытался добавить идентификатор пользователя в форму до метода save()
следующим образом: form.cleaned_data['created_by'] = 1
и form.cleaned_data['created_by_id'] = 1
. Но ничто из этого не работает.
Может кто-нибудь объяснить мне, как я могу добавить дополнительные материалы к представленной модели модели, чтобы сохранить ее?
class Location(models.Model):
name = models.CharField(max_length = 100)
created_by = models.ForeignKey(User)
create_date = models.DateTimeField(auto_now=True)
class LocationForm(forms.ModelForm):
class Meta:
model = Location
exclude = ('created_by', 'create_date', )
Ответы
Ответ 1
Так как вы исключили поля created_by
и create_date
в своей форме, попытка их назначения через form.cleaned_data
не имеет никакого смысла.
Вот что вы можете сделать:
Если у вас есть представление, вы можете просто использовать form.save(commit=False)
, а затем установить значение created_by
def my_view(request):
if request.method == "POST":
form = LocationForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.created_by = request.user
obj.save()
...
...
`
Если вы используете Admin, вы можете переопределить метод save_model(), чтобы получить желаемый результат.
class LocationAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.created_by = request.user
obj.save()
Ответ 2
Передайте пользователя как параметр для создания конструктора, затем используйте его для установки поля created_by экземпляра модели:
def add_location(request):
...
form = LocationForm(user=request.user)
...
class LocationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(forms.ModelForm, self).__init__(*args, **kwargs)
self.instance.created_by = user
Ответ 3
Правильное решение - передать экземпляр объекта с предварительно заполненными полями в конструктор формы модели. Таким образом, поля будут заполнены во время проверки. Присвоение значений после form.save()
может привести к ошибкам проверки, если требуются поля.
LocationForm(request.POST or None, instance=Location(
created_by=request.user,
create_date=datetime.now(),
))
Обратите внимание, что экземпляр является несохраненным объектом, поэтому идентификатор не будет назначен до тех пор, пока форма не сохранит его.
Ответ 4
Один из способов сделать это - использовать form.save(commit = False) (doc)
Это вернет экземпляр объекта класса модели, не передавая его в базу данных.
Итак, ваша обработка может выглядеть примерно так:
form = some_form(request.POST)
location = form.save(commit=False)
user = User(pk=1)
location.created_by = user
location.create_date = datetime.now()
location.save()