如何在CreatView中获取对象

时间:2019-07-18 12:28:32

标签: django django-models django-forms django-views

有一种由url呈现的表单

url(r'kredit/(?P<credit_slug>[-\.\w\d]+)/$', CreditDetail.as_view(), name='credit_detail'),

网址

url(r'kredit/(?P<credit_slug>[-\.\w\d]+)/$', CreditDetail.as_view(), name='credit_detail'),
url(r'kredit_request/$', CreditOnlineRequestView.as_view(), name='credit_request'),

CreditOnlineRequestView(CreateView)视图中处理表单。 有必要从其中的CreditDetail视图中拉出credit_slug(在此处绘制表格)

观看次数

class CreditDetail(FormView):
    form_class = CreditPaymentForm
    template_name = 'credits/credit_detail.html'
​
    def get_initial(self):
        initial = super(CreditDetail, self).get_initial()
        initial['request'] = self.request
        return initial
​
    def get(self, *args, **kwargs):
        request_form = CreditOnlineRequestForm(self.request.GET or None, prefix="request")
​
​
class CreditOnlineRequestView(CreateView):
    form_class = CreditOnlineRequestForm
    model = CreditOnlineRequest
    template_name = 'credits/credit_listing.html'
    prefix = 'request'
​
    def form_valid(self, form, **kwargs):
        credit_request = form.save(commit=False)
        credit_request.credit = credit                     #???
        return super(CreditOnlineRequestView, self).form_valid(form)
​
    def form_invalid(self, form):
        errors = dict([(k, v[0]) for k, v in form.errors.items()])
        return errors

表格

class CreditOnlineRequestForm(forms.ModelForm):
    class Meta:
        model = CreditOnlineRequest
        exclude = ['credit']           #this field must be define
​
    def __init__(self, *args, **kwargs):
        super(CreditOnlineRequestForm, self).__init__(*args, **kwargs)
        #???

有哪些选择?我认为是通过cache还是通过退出previous page来完成,但是就我而言,这在某种程度上不是很人道。对我来说,最好的选择是将信用实例转移到hidden form field视图中的CreditDetail上,但是我还不知道该怎么做。

2 个答案:

答案 0 :(得分:1)

问题是内部form_valid函数正在执行以下操作:

def form_valid(self, form):
    """If the form is valid, save the associated model."""
    self.object = form.save()
    return super().form_valid(form)

因此,超级操作将尝试直接保存表单,这与您在覆盖中的操作无关。您可以通过以下方法解决问题:

def form_valid(self, form, **kwargs):
    credit_request = form.save(commit=False)
    credit_request.credit = credit
    credit_request.save()
    return HttpResponseRedirect(self.get_success_url())

答案 1 :(得分:0)

网址

url(r'kredit_request/(?P<credit_slug>[-\.\w\d]+)/$', CreditOnlineRequestView.as_view(), name='credit_request'),

html

<form action="{% url 'credit_request' credit.slug %}" method="post">

视图

class CreditOnlineRequestView(CreateView):
    form_class = CreditOnlineRequestForm
    model = CreditOnlineRequest
    slug_url_kwarg = 'credit_slug'
    prefix = 'request'

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        credit = Credit.objects.get(slug=kwargs.get('credit_slug'))
        cache.set('credit_for_request', credit)
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        credit_request = form.save(commit=False)
        credit = cache.get('credit_for_request')
        cache.clear()
        credit_request.credit = credit
        credit_request.save()
        return HttpResponseRedirect(reverse('credit_detail', kwargs={'credit_slug': credit.slug}))