Как позволить универсальному представлению Django использовать форму с начальными значениями? - PullRequest
2 голосов
/ 25 мая 2009

Я знаю, как установить начальные значения в форме из представления. Но как мне разрешить универсальному представлению задавать начальные значения для формы? Я могу написать представление-обертку для общего представления, но у меня все еще нет доступа к созданию экземпляра объекта формы.

Конкретная цель, которую я пытаюсь достичь, состоит в том, чтобы пользователь создал новый объект, используя общее представление create_object. Тем не менее, я хотел бы установить поле объекта 'user' для текущего вошедшего в систему пользователя, которое доступно только как request.user. Как можно инициализировать форму, чтобы иметь это поле?

Редактировать: я наткнулся на __new__. Может ли это вызвать собственный конструктор с некоторыми аргументами по умолчанию?

Большое спасибо.

Ответы [ 3 ]

4 голосов
/ 26 мая 2009

К сожалению, вы не можете достичь этого поведения с помощью общего представления Django create_object; вам придется написать свой. Однако это довольно просто.

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

from django import forms
class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel  # model has a user field

Тогда вы сможете создать вид, подобный этому:

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required

@login_required
def create_mymodel(request):
    if request.method == 'POST':
        # Get data from form
        form = MyForm(request.POST)
        # If the form is valid, create a new object and redirect to it.
        if form.is_valid():
            newObject = form.save()
            return HttpResponseRedirect(newObject.get_absolute_url())
    else:
        # Fill in the field with the current user by default
        form = MyForm(initial={'user': request.user})
    # Render our template
    return render_to_response('path/to/template.html',
        {'form': form},
        context_instance=RequestContext(request))
3 голосов
/ 26 мая 2009

Вы можете сделать это в оболочке общего вида, динамически создав класс формы и передав его в общее представление, но это лекарство, вероятно, хуже, чем болезнь. Просто напишите свое собственное мнение и с нетерпением ждите, пока этот приземлится.

0 голосов
/ 20 января 2012

Если вам нужны все функции общего вида, вы можете просто создать новый общий вид, используя оригинал в качестве шаблона.

Например:

def create_object_with_initial(request, model=None, template_name=None,
    template_loader=loader, extra_context=None, post_save_redirect=None,
    login_required=False, context_processors=None, form_class=None, initial=None):

if extra_context is None: extra_context = {}
if login_required and not request.user.is_authenticated():
    return redirect_to_login(request.path)

model, form_class = get_model_and_form_class(model, form_class)
if request.method == 'POST':
    form = form_class(request.POST, request.FILES)
    if form.is_valid():
        new_object = form.save()

        msg = ugettext("The %(verbose_name)s was created successfully.") %\
                                {"verbose_name": model._meta.verbose_name}
        messages.success(request, msg, fail_silently=True)
        return redirect(post_save_redirect, new_object)
else:
    print "creating", form_class, " with initial data ", initial
    form = form_class(initial=initial)

# Create the template, context, response
if not template_name:
    template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
t = template_loader.get_template(template_name)
c = RequestContext(request, {
    'form': form,
}, context_processors)
apply_extra_context(extra_context, c)
return HttpResponse(t.render(c))

Это скопировано из /site-packages/django/views/generic/create_update.py с изменениями только строк 3 и 21 для включения исходных данных.

Тогда используйте его, как вы могли ожидать:

object_info = {
'model': YourModel,
'initial': {'data' : 'Initial Value'},
'template_name': 'template.html'
}

url(r'^path/$',
    login_required(create_object_with_initial),
    object_info,
    name='url_name'),

Это должно сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...