0

djangoフォームに非常に奇妙な問題があります。追加のフォームセットを含むフォームを表示して、ユーザーが同時に外部キー関係のデータを送信できるようにします。

テンプレートには、元のモデル用のフォームと 2 番目のモデル用のフォームが常に表示されます。

2 番目のフォームには何も入力せずに、2 つのフォームを送信したいと考えています。最初の送信では 2 番目のフォームは検証されず、ページが再表示されますが、2 回目の送信では 2 番目のフォームが有効です。それでも、POST データは同じです。これはどのように可能ですか?

または、私はこれを完全に間違っているのかもしれません。ユーザーがフォームセットに何も入力していないか、無効なものを入力したかをどのように見分けることができますか?

モデルは次のとおりです。

class Software(models.Model):
    creation_date = models.DateTimeField(default=datetime.now)
    creator = models.ForeignKey(User)
    version = models.CharField(max_length=300, unique=True, editable=False)
    major_version = models.IntegerField()
    minor_version = models.IntegerField()
    [...]

    def save(self, **kwargs):
        """
        This updates the version string to the combined representation.
        """
        self.version = Software.combine_version_string (self.major_version, self.minor_version)
        super(Software, self).save(**kwargs)

class SoftwarePatch(models.Model):
    file  = models.FileField(upload_to='software_patches')
    file_name = models.CharField(max_length=255, editable=False)
    file_date = models.DateTimeField(default=datetime.now)
    upload_date = models.DateTimeField(default=datetime.now)
    software = models.ForeignKey('Software', related_name='patches')
    firmware_patch = models.BooleanField(default=True)
    target_path = models.CharField(max_length=255, blank=True)

    class Meta:
        unique_together = ('software', 'file_name')
        verbose_name_plural = "software patches"

    def __unicode__(self):        
        return self.file_name

    def clean(self):
          if self.file and not self.file_name:
              self.file_name = self.file.file.name 

ここに私のフォーム:

SoftwarePatchFormSet = inlineformset_factory(Software, 
    SoftwarePatch, 
    extra=1)


class SoftwareForm(forms.ModelForm):
    """
    A simple form for creating a new software.
    """
    class Meta:
        model = Software

そして最後に私のビュー関数:

def software_add(request, software_id=None):
    if software_id == None:
        software = Software()
    else:
        software = Software.objects.get(id=software_id)

    if request.POST:        
        form = SoftwareForm(request.POST, instance=software)        

        if form.is_valid():
            software = form.save(commit=False)
            softwarepatch_formset = SoftwarePatchFormSet(request.POST, request.FILES, instance=software)

            if softwarepatch_formset.is_valid():
                software = form.save()
                softwarepatch_formset.save()

                # Redirect, in case of a popup close it
                if request.POST.has_key("_popup"):
                    pk_value = software._get_pk_val()
                    return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
                        # escape() calls force_unicode.
                        (escape(pk_value), escape(software)))
                if 'next' in request.POST:
                    return HttpResponseRedirect(request.POST['next'])
                else:
                    return HttpResponseRedirect(reverse('index'))
    else:
        form = SoftwareForm(instance=software)
        softwarepatch_formset = SoftwarePatchFormSet(instance=software)

    is_popup = request.GET.has_key("_popup") or request.POST.has_key("_popup")

    return render_to_response(
        'main/software_edit.html',
        {'form': form,
         'softwarepatch_formset': softwarepatch_formset,
         'add': True,
         'is_popup': is_popup,
        },
        context_instance = RequestContext(request)
    )
4

2 に答える 2

1

わかりました私はついに私の問題を見つけました!

次のモデル フィールドがあります: file_date = models.DateTimeField(default=datetime.now)

これにより、初期ファイル日付が次のような値に設定されます。 30' したがって、django はフォームが変更されたと判断し、保存しません。

2 回目の読み込みで、django は切り捨てられた値を initial-file-date として自動的に設定し、何も変更されず、保存は期待どおりに機能します。

そのため、datetime.now の代わりに何を使用するかを理解するだけです。わかり次第、この記事を更新します。

于 2011-10-19T05:11:18.113 に答える