Django, добавление исключенных свойств в представленную модель - PullRequest
11 голосов
/ 29 апреля 2011

У меня есть форма модели, и я исключил два поля, поля 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', )

Ответы [ 4 ]

18 голосов
/ 29 апреля 2011

Поскольку вы исключили поля 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()
4 голосов
/ 29 апреля 2011

Передайте пользователя в качестве параметра для конструктора формы, а затем используйте его для установки поля selected_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
2 голосов
/ 16 июня 2016

Правильное решение - передать экземпляр объекта с предварительно заполненными полями в конструктор формы модели.Таким образом, поля будут заполнены во время проверки.Назначение значений после form.save() может привести к ошибкам проверки, если поля обязательны для заполнения.

LocationForm(request.POST or None, instance=Location(
    created_by=request.user,
    create_date=datetime.now(),
))

Обратите внимание, что экземпляр является несохраненным объектом, поэтому идентификатор не будет назначен, пока форма не сохранит его.

0 голосов
/ 29 апреля 2011

Один из способов сделать это - использовать 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()
...