2010-01-02 15 views
22

ile özel formlarının bir Formset başlatılıyor: Ben Noktaları düzenleme listeleri için bir form oluşturmak çalışıyorumDjango: Aşağıdaki modeller Verilen örneklerde

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 girişi etiketleri ayarlanmasına ek özellikler gerektiren, bu yüzden aşağıdaki özel bir form kullanıyorum:

: Bu noktada

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') 

Bir FormSet gelin sınıfının örneklerini geçmesine nasıl bilmiyorum

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? 
Ben biraz çalışan bir hack buldum ama ortaya çıkan POST verilerini işleme koymaya çalışırken daha sonra hatalara yol açar:
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) 

Bu nasıl doğru yapılır? Başvuru için

, benim şablon şöyle görünür:

<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> 

cevap

23

hüner bir sorgu kümesi ile başlatma izin beri "ModelFormset" yerine sadece bir formset kullanmaktır. Dokümanlar, here şeklindedir, yaptığınız şey, form kümesini başlatırken model formset ve queryset = * oluştururken bir form = * sağlar. Biçim = * tartışması iyi belgelenmemiş (aslında orada olduğundan emin olmak için kodda biraz dolaşmak zorunda kaldı). Bu nedenle kod kolayca geçiyor demektir. İstek bir GET ise, örneklenen form kullanıcıya gönderilir. İstek bir POST ise ve form not .is_valid() ise, hatalar "düşer" ve aynı şablonda döndürülür. İstek bir POST ise ve veriler geçerliyse, form kümesi kaydedilir.

Bu yardımcı olur umarım.

-Will

+1

Ahhhh, çok teşekkür ederim, bu çok güzel çalışıyor. Küçük düzeltme: POST verilerini doğrularken, başlatma şöyle görünür: "PointFormset (request.POST, queryset = qset)". Else, bu hatayı alırsınız: "Bu tarihe sahip nokta zaten var". – knipknap

+0

doh ... iyi yakalama ... Model_formset ve sağlanan verileri kullanırken queryset'i vermeniz gerektiğini de unutmuştum ... Bu kullanım vakasında aslında hiç bir zaman kullanmadım. – JudoWill

0

sadece belki değerlerden kapalı bir olası ayarlamak istediğiniz değere veya varsa, kullanarak kullanıcı İLETİLERİNDE sonra sunucuya veri bunları ayarlamak mümkündür commit=False

Lütfen aşağıdaki kodu dikkate alın:

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')) 
İlgili konular