Как установить свойство экземпляра модели при использовании универсального представления для его создания? - PullRequest
0 голосов
/ 18 января 2009

Допустим, мы пытаемся использовать django.views.generic.create_update.create_object, чтобы позволить пользователю создать экземпляр записи в блоге. В модели Entry есть обязательное поле для пользователя, которое я не хочу показывать в качестве редактируемого поля в форме записи блога. Итак, я бы включил его в кортеж EntryForm.Meta.exclude.

Где я должен установить значение для пользовательского свойства в результирующем экземпляре модели? Должен ли я прекратить использовать универсальный вид create_object и написать свой собственный?

Ответы [ 3 ]

2 голосов
/ 18 января 2009

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

(адаптировано с http://www.djangobook.com/en/1.0/chapter07/)

from yourmodel.forms import EntryForm

def create_entry(request):
    if request.method == 'POST':
        form = EntryForm(request.POST)
        if form.is_valid():
            entry = form.save(commit = false)
            entry.author = request.user.username
            entry.save()
            return HttpResponseRedirect('/create_entry/thanks/')
    else:
        form = EntryForm()
    return render_to_response('/path/to/template.html', {'form' : form, ...}, ...)

Конечно, вам придется использовать свои собственные имена и тому подобное, но это логика. В основном вы проверяете, была ли отправлена ​​форма, и, если это так, получите Entry, добавьте имя пользователя и сохраните его как обычно. Что касается отличий от общего представления create_object, то вместо указания таких вещей, как post_redirect_url в вызове представления, вы даете их напрямую. Проверьте документы render_to_response и HttpResponseRedirect для получения дополнительной информации.

1 голос
/ 25 марта 2012

Мне просто нужно было решить эту проблему, и я не хотел обманывать. Это было не сложно. Проверьте ниже.

Пожалуйста, обратите внимание, что это только запутанно, потому что я решил придерживаться своего взгляда на разделение MVC по этому вопросу. Население пользователя зависит от вида (так как у нас нет специального начального пользователя в Edit). Обработка зависит от модели.

Нетрудно извлечь миксин формы, который ожидает новый параметр "passthrough" и автоматически объединяет исключение с пересылкой исходных данных. Это также добавляет безопасность знания того, что никто не может изменять данные этих полей в представлении.

class TestForm(forms.ModelForm):

    class Meta:
        exclude = ('user')
        model = models.Test

    def save(self, commit=True):
        obj = super(CharmForm, self).save(commit=False)
        obj.user = self.initial['user']

        if commit:
            obj.save()

class TestView(CreateView):
    model = models.Test
    form_class = TestForm
    def get_initial(self,**kwargs):
        initial = super(CreateView,self).get_initial()

        c = RequestContext(self.request)

        initial = initial.copy()
        initial['user'] = c['user']
        return initial

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

0 голосов
/ 13 апреля 2009

Существует одна маленькая проблема с решением sykora: если форма недействительна, вы получите ошибку, потому что форма не будет установлена ​​(вне области действия оператора if).

Вот немного лучшая версия:

from yourmodel.forms import EntryForm

def create_entry(request):
    form = EntryForm()
    if request.method == 'POST':
        form = EntryForm(request.POST)
        if form.is_valid():
            entry = form.save(commit = false)
            entry.author = request.user.username
            entry.save()
            return HttpResponseRedirect('/create_entry/thanks/')
    return render_to_response('/path/to/template.html', {'form' : form, ...}, ...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...