2009-12-06 13 views
36

मैंने इसे एक अच्छा फॉर्म बनाया है, और इसे संभालने के लिए एक बड़ा जटिल 'एड' फ़ंक्शन बनाया है। यह इस तरह से शुरू होता है ...Django एड फॉर्म के आधार पर फॉर्म संपादित करें?

def add(req): 
    if req.method == 'POST': 
     form = ArticleForm(req.POST) 
     if form.is_valid(): 
      article = form.save(commit=False) 
      article.author = req.user 
      # more processing ... 

अब मैं वास्तव में नहीं है edit() विधि में सभी कि कार्यक्षमता डुप्लिकेट करना चाहते हैं, तो मैं edit लगा ठीक उसी टेम्पलेट का उपयोग कर सकता है, और हो सकता है सिर्फ एक id क्षेत्र में जोड़ने के लिए फॉर्म add फ़ंक्शन जानता था कि यह संपादन क्या कर रहा था। लेकिन इस

  1. मैं कहां से add समारोह में article.id स्थापित करेगा साथ एक जोड़ी समस्याओं है? इसे form.save के बाद होना चाहिए क्योंकि वह लेख कहां बनाया गया है, लेकिन यह कभी भी उस तक पहुंच नहीं पाएगा, क्योंकि अद्वितीय बाधाओं के कारण फ़ॉर्म अमान्य है (जब तक उपयोगकर्ता ने सबकुछ संपादित नहीं किया हो)। मैं सिर्फ is_valid चेक को हटा सकता हूं, लेकिन फिर form.save इसके बजाय विफल रहता है।
  2. यदि फॉर्म वास्तव में अमान्य है, तो फ़ील्ड जिसे मैंने गतिशील रूप से संपादन फ़ंक्शन में जोड़ा है, संरक्षित नहीं है।

तो मैं इससे कैसे निपटूं?

उत्तर

88

आप एक ModelForm से अपने फार्म का विस्तार कर रहे हैं, instance कीवर्ड तर्क का उपयोग करें। यहां हम या तो मौजूदा instance या एक नया पास करते हैं, इस पर निर्भर करते हुए कि हम मौजूदा लेख को संपादित या जोड़ रहे हैं या नहीं। दोनों मामलों में author फ़ील्ड उदाहरण पर सेट है, इसलिए commit=False आवश्यक नहीं है। ध्यान दें कि मुझे लगता है कि केवल लेखक ही अपने लेख संपादित कर सकते हैं, इसलिए HttpResponseForbidden प्रतिक्रिया।

from django.http import HttpResponseForbidden 
from django.shortcuts import get_object_or_404, redirect, render, reverse 


@login_required 
def edit(request, id=None, template_name='article_edit_template.html'): 
    if id: 
     article = get_object_or_404(Article, pk=id) 
     if article.author != request.user: 
      return HttpResponseForbidden() 
    else: 
     article = Article(author=request.user) 

    form = ArticleForm(request.POST or None, instance=article) 
    if request.POST and form.is_valid(): 
     form.save() 

     # Save was successful, so redirect to another page 
     redirect_url = reverse(article_save_success) 
     return redirect(redirect_url) 

    return render(request, template_name, { 
     'form': form 
    }) 

और अपने urls.py में:

(r'^article/new/$', views.edit, {}, 'article_new'), 
(r'^article/edit/(?P<id>\d+)/$', views.edit, {}, 'article_edit'), 

ही edit दृश्य दोनों के लिए प्रयोग किया जाता है कहते हैं और संपादन, लेकिन केवल संपादित यूआरएल ढांचा देखने के लिए एक आईडी से गुजरता है। अपने फार्म के साथ अच्छी तरह से यह काम करने के लिए आप फार्म से author क्षेत्र छोड़ करना होगा:

class ArticleForm(forms.ModelForm): 
    class Meta: 
     model = Article 
     exclude = ('author',) 
+0

हाँ, यह एक 'ModelForm' है। मुझे अन्य कारणों से 'प्रतिबद्ध = गलत 'की आवश्यकता थी। एक लेख सामग्री के पूरे समूह (कुछ एम 2 एम संबंधों सहित) से बना है। मैं नहीं सोचता * यह 'इंस्टेंस' के साथ काम करना चाहता था। हालांकि मैं इसे आज़मा दूंगा। – mpen

+1

उस स्थिति में, मैं सुझाव के बजाय फॉर्म में एम 2 एम संबंध (एट अल) बचत/सत्यापन डालने का सुझाव दूंगा ... या तो सहेजने की विधि को ओवरराइड करें या संभवतः फॉर्मेट्स में देखें। मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप किसके साथ काम कर रहे हैं ... –

+5

महान और गहन उदाहरण! धन्यवाद! मैंने इस सवाल के समाधान के मुकाबले ज्यादा सीखा। – hobbes3

1

आपके पास फॉर्म में छिपी हुई आईडी फ़ील्ड हो सकती है और संपादन फ़ॉर्म के लिए इसे फॉर्म के रूप में पास किया जाएगा जिसे आप इसे req.POST में सेट कर सकते हैं।

formData = req.POST.copy() 
formData['id'] = getNewID() 

और पारित कि formData बनाने के लिए

संबंधित मुद्दे