2010-01-02 8 views
22

निम्नलिखित मॉडल को देखते हुए के साथ कस्टम रूपों की एक formset शुरु कर रहा है:Django: उदाहरणों

class Graph(models.Model): 
    owner = models.ForeignKey(User) 

    def __unicode__(self): 
     return u'%d' % self.id 

class Point(models.Model): 
    graph = models.ForeignKey(Graph) 
    date = models.DateField(primary_key = True) 
    abs = models.FloatField(null = True) 
    avg = models.FloatField(null = True) 

    def __unicode__(self): 
     return u'%s' % self.date 

मैं अंक के संपादन सूचियों के लिए एक फार्म बनाने के लिए कोशिश कर रहा हूँ। HTML इनपुट टैग अतिरिक्त गुण सेट करने के लिए आवश्यकता होती है, तो मैं निम्नलिखित कस्टम प्रपत्र का उपयोग कर रहा हूँ:

:

class PointForm(forms.ModelForm): 
    graph = forms.ModelChoiceField(queryset = Graph.objects.all(), 
            widget = forms.HiddenInput()) 
    date = forms.DateField(widget = forms.HiddenInput(), label = 'date') 
    abs = forms.FloatField(widget = forms.TextInput(
             attrs = {'class': 'abs-field'}), 
          required = False) 

    class Meta: 
     model = Point 
     fields = ('graph', 'date', 'abs') # Other fields are not edited. 

    def pretty_date(self): 
     return self.data.strftime('%B') 

इस बिंदु पर मैं कैसे एक formset को इंगित वर्ग के उदाहरण पारित करने के लिए पता नहीं है

def edit(request): 
    PointFormSet = forms.formsets.formset_factory(PointForm, extra = 0) 
    if request.method == 'POST': 
     return 

    # Receive 3 points to edit from the database. 
    graph, res = Graph.objects.get_or_create(id = 1) 
    one_day = datetime.timedelta(days = 1) 
    today  = datetime.date.today() 
    do_edit = [] 
    for date in [today - (x * one_day) for x in range(3)]: 
     point, res = Point.objects.get_or_create(graph = graph, date = date) 
     do_edit.append(point) 

    formset = PointFormSet(????) # How is this initialized with the points? 

मैं एक हैक है कि कुछ हद तक काम करता है पाया, लेकिन जब जिसके परिणामस्वरूप पोस्ट डेटा की प्रक्रिया करने की कोशिश कर इसे बाद में त्रुटियां होती हैं:

do_edit = [] 
for date in [today - (x * one_day) for x in range(3)]: 
    point, res = Point.objects.get_or_create(graph = graph, date = date) 
    data   = point.__dict__.copy() 
    data['graph'] = graph 
    do_edit.append(data) 

formset = PointFormSet(initial = do_edit) 

यह कैसे सही ढंग से किया जाता है?

संदर्भ के लिए, मेरे टेम्पलेट इस तरह दिखता है:

<form action="" method="post"> 
{{ formset.management_form }} 
<table> 
    <tbody> 
    {% for form in formset.forms %} 
     <tr> 
      <td>{{ form.graph }} {{ form.date }} {{ form.pretty_date }}:</td> 
      <td width="100%">{{ form.abs }}</td> 
     </tr> 
    {% endfor %} 
    </tbody> 
</table> 
</form> 

उत्तर

23

चाल एक "ModelFormset" के बजाय सिर्फ एक formset का उपयोग करने के बाद से वे एक क्वेरीसमूह के साथ प्रारंभ अनुमति देते हैं। दस्तावेज़ here हैं, जो आप फॉर्मेट को तत्काल बनाते समय मॉडल फॉर्मेट और क्वेरीसेट = * बनाते समय एक फॉर्म = * प्रदान करते हैं। फॉर्म = * बहस अच्छी तरह से प्रलेखित नहीं है (यह सुनिश्चित करने के लिए कोड में चारों ओर खोदना था कि यह वास्तव में वहां है)।

def edit(request): 
    PointFormSet = modelformset_factory(Point, form = PointForm) 
    qset = Point.objects.all() #or however your getting your Points to modify 
    formset = PointFormset(queryset = qset) 
    if request.method == 'POST': 
     #deal with posting the data 
     formset = PointFormset(request.POST) 
     if formset.is_valid(): 
      #if it is not valid then the "errors" will fall through and be returned 
      formset.save() 
     return #to your redirect 

    context_dict = {'formset':formset, 
        #other context info 
        } 

    return render_to_response('your_template.html', context_dict) 

तो कोड आसानी से चलता है। अगर अनुरोध प्राप्त होता है तो तत्काल फॉर्म उपयोगकर्ता को वापस कर दिया जाता है। अगर अनुरोध एक पोस्ट है और फॉर्म not .is_valid() है तो त्रुटियां "गिरती हैं" और उसी टेम्पलेट में लौटा दी जाती हैं। अगर अनुरोध एक पोस्ट है और डेटा मान्य है तो फॉर्मेट सहेजा गया है।

उम्मीद है कि मदद करता है।

-Will

+1

Ahhhh, आप बहुत बहुत धन्यवाद, कि खूबसूरती से काम करता है। मामूली सुधार: POST डेटा को सत्यापित करते समय, प्रारंभिकरण इस तरह दिखता है: "प्वाइंटफ़ॉर्मसेट (request.POST, queryset = qset)"। अन्यथा आपको यह त्रुटि मिल जाएगी: "इस तिथि के साथ बिंदु पहले से मौजूद है"। – knipknap

+0

दोह ... अच्छा पकड़ ... मैं भूल गया कि मॉडल_फॉर्मसेट और प्रदान किए गए डेटा का उपयोग करते समय आपको क्वेरीसेट देने के लिए भी आवश्यक ... मैंने कभी भी इस उपयोग-मामले के लिए उपयोग नहीं किया है। – JudoWill

0

आप केवल एक संभावित मान जो आप सेट करना चाहते, या शायद मूल्यों की एक बंद कर दिया है, तो यह उपयोग कर अपने सर्वर से डेटा उपयोगकर्ता पोस्ट के बाद उन्हें स्थापित करने के लिए संभव है commit=False

कृपया निम्नलिखित कोड पर विचार करें:

class UserReferralView(View): 
    ReferralFormSet = modelformset_factory(ReferralCode, 
              form=ReferralTokenForm, extra=1) 

    def get(self, request): 
     pass 

    def post(self, request): 
     referral_formset = UserUpdateView.ReferralFormSet(request.POST) 

     if referral_formset.is_valid(): 
      instances = referral_formset.save(commit=False) 
      for instance in instances: 
       instance.user = request.user 
       instance.save() 
      return redirect(reverse('referrals.success_view')) 
     else: 
      return redirect(reverse('referrals.failure_view')) 
संबंधित मुद्दे