1

フォームを保存していますが、トランザクションの外にある save() メソッドが 1 つあります。トランザクション外の save() メソッドは、「BicycleAdCategoryForm」の save() です。

コードは次のとおりです。

models.py

class Main(models.Model):
    section             = models.ForeignKey(Section)
    user                = models.ForeignKey(User)
    title               = models.CharField(max_length=250)
    date_inserted       = models.DateTimeField(auto_now_add=True)
    date_last_update    = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.title

    # To order in the admin by name of the section
    class Meta:
        ordering = ['date_inserted']

class BicycleAd(models.Model):
    main                = models.ForeignKey(Main)
    bicycleadtype       = models.ForeignKey(BicycleAdType)
    bicycleaditemkind   = models.ForeignKey(BicycleAdItemKind) # MPTT Model
    bicycleadcondition  = models.ForeignKey(BicycleAdCondition)
    country             = models.ForeignKey(GeonamesCountry)       
    city                = models.ForeignKey(GeonamesLocal) 
    date_inserted       = models.DateTimeField(auto_now_add=True)
    date_last_update    = models.DateTimeField(auto_now=True)

    # To order in the admin by name of the section
    class Meta:
        ordering = ['date_inserted']   


class BicycleAdCategoryType(models.Model):
    n_bicycle_ad_category_type = models.CharField(max_length=100) # COMPRA, VENDA, TROCA
    date_inserted              = models.DateTimeField(auto_now_add=True)
    date_last_update           = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.n_bicycle_ad_category_type

    # To order in the admin by name of the section
    class Meta:
        ordering = ['n_bicycle_ad_category_type'] 

フォーム.py

class MainForm(forms.ModelForm):
    class Meta:
        model = Main
        exclude = ('user', 'section')

class BicycleAdForm(forms.ModelForm):
    class Meta:
        model = BicycleAd
        exclude = ('main', 'bicycleadtype', 'bicycleaditemkind', 'bicycleadcondition', 'city') # DPS RETIRAR DAQUI A "CITY"

class BicycleAdCategoryForm(forms.ModelForm):
    bicycleadcategorytype = forms.ModelMultipleChoiceField(queryset=BicycleAdCategoryType.objects.all(), required=False, widget=forms.CheckboxSelectMultiple) # Se retirar o widget fico uma SELECT box em q posso selecionar varias opcoes

    class Meta:
        model = BicycleAdCategory
        exclude = ('bicyclead',)

    def save(self, commit, rel_obj):
        data = self.data.getlist('bicycleadcategorytype')
        for item in data:
            obj_bicycleadcategory = BicycleAdCategory()
            obj_bicycleadcategory.bicyclead = rel_obj
            obj_bicycleadcategory.bicycleadcategorytype = BicycleAdCategoryType.objects.get(pk=item)
            obj_bicycleadcategory.save()

    def clean_bicycleadcategorytype(self):
        data = self.cleaned_data['bicycleadcategorytype']
        try:
            for item in data:
                bicycleadcategorytype = BicycleAdCategoryType.objects.get(pk=item.pk)
            return bicycleadcategorytype
        except (KeyError, BicycleAdCategoryType.DoesNotExist):
            raise forms.ValidationError('Invalid Bicycle Ad Category Type. Please try again.')    

ビュー.py

def submit_ad_view(request):
    if request.method == 'POST':      
        model_main = Main()
        model_main.section = Section.objects.get(pk=request.POST['section'])
        model_main.user = request.user

        model_bicyclead = BicycleAd()
        model_bicyclead.bicycleadtype = BicycleAdType.objects.get(pk=2)
        model_bicyclead.bicycleaditemkind = BicycleAdItemKind.objects.get(pk=4)
        model_bicyclead.bicycleadcondition = BicycleAdCondition.objects.get(pk=2)
        model_bicyclead.city = GeonamesLocal.objects.get(pk=4803854)


        form_main = MainForm(request.POST, instance = model_main)
        form_bicyclead = BicycleAdForm(request.POST, instance = model_bicyclead)
        form_bicycleadcategory = BicycleAdCategoryForm(request.POST)

        if form_main.is_valid() and form_bicyclead.is_valid() and form_bicycleadcategory.is_valid():
            main_f = form_main.save()

            bicyclead_f = form_bicyclead.save(commit=False)
            bicyclead_f.main = main_f
            bicyclead_f.save()

            bicycleadcategory_f = form_bicycleadcategory.save(commit=False, rel_obj=model_bicyclead)


            resultado = 'valid'
        else:
            resultado = 'n_valid'


    return render_to_response('app/submit_ad.html', {'resultado': resultado}, context_instance=RequestContext(request))

main_f と bicyclead_f はトランザクション内にあると思いますが、bicycleadcategory_f はトランザクション外です。Bicycleadcategory_f が失敗すると、main_f と bicyclead_f がデータベースに格納されます。

私が間違っていることについての手がかりはありますか?

よろしくお願いします、

4

1 に答える 1

1

Djangoはcommit_on_successデコレータを使用してビューを実行します(または少なくともそのように動作します)。ビューのクラッシュ(キャッチされない例外)が発生した場合は、ロールバックを実行する必要があります。一部のデータが保存されていて、一部が保存されていない場合、DBエンジンがトランザクション処理をサポートしていない可能性があります。

詳細については、djangoドキュメントを確認してください https://docs.djangoproject.com/en/dev/ref/databases/

たとえば、MyISAMでMySQLを使用している場合、いくつかの問題が発生する可能性があります

編集: Krzysiek Szularz:誰もがdjango TransactionMiddlewareまたは同様のものを使用していると思うので、スキップしました-ロジックレイヤーについてのみ言及しました。

于 2013-01-07T12:54:27.753 に答える