Какой самый чистый способ добавить произвольные данные в ModelForm? - PullRequest
0 голосов
/ 10 октября 2011

Представьте, что мы разрабатываем систему сообщений, и у каждого Message есть внешний ключ для sender.

Мы используем ModelForm s, и есть MessageForm, который выводит его поля из Message.
Конечно, мы не хотим, чтобы пользователь могподделать sender, опубликовав другой идентификатор отправителя .

Поэтому мы должны исключить sender из ModelForm и заполнить его из session в сообщении.

Где и как я должен назначить произвольные данные полям ModelForm?

В моем примере я, вероятно, хочу получить доступ к session, поэтому нам нужен доступ кrequest.
Означает ли это, что код должен быть в представлении сразу после создания формы?

Как нам назначить поле формы из кода и убедиться, что оно переопределяет данные POST?

(Конечно, пример довольно вымышленный и приведен здесь только для иллюстрации проблемы.)

Ответы [ 2 ]

1 голос
/ 10 октября 2011

Вы можете просто исключить его как есть, а затем при обработке формы в представлении сделать:

obj = form.save(commit=False)
obj.sender = request.user
obj.save()

Кроме того, вы можете сделать это в методе сохранения формы; Для этого вам необходимо на мгновение сохранить объект запроса в форме. Примерно так:

class MyForm(forms.ModelForm):
  def __init__(self, request, *args, **kwargs):
    self._request = request
    super(MyForm, self).__init__(*args, **kwargs)

  def save(self, commit=False):
    obj = super(MyForm, self).save(commit=False)
    obj.sender = self._request.user
    if commit:
      obj.save()

    return obj

Я сам предпочитаю второй способ, поскольку он помогает инкапсулировать логику, касающуюся этой модели и ее данных в одном аккуратном месте.

1 голос
/ 10 октября 2011

Просто исключите поле sender из ModelForm и, когда вы создаете экземпляр объекта в представлении на конечной точке POST (непосредственно перед сохранением), убедитесь, что вы заполнили поле sender соответствующим сеансом или пользователем ID.

Когда вы исключаете поле, невозможно добавить поле к данным поста [1], поэтому пользователь не может подделать его.

[1] С помощью JavaScript теоретически можно добавить &sender=someSenderId, но, на ваш взгляд, вам не нужно искать поле отправителя. Он не будет сериализован в объект ModelForm.

...