1

我正在保存一个表单,但是事务之外有一个 save() 方法。事务外的 save() 方法是“BicycleAdCategoryForm”上的 save()。

这是代码:

模型.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 和 bikead_f 在事务内,但 bikeadcategory_f 在事务外。当bikeadcategory_f 失败时,main_f 和bikead_f 存储在数据库中。

关于我做错了什么的任何线索?

此致,

4

1 回答 1

1

Django 使用 commit_on_success 装饰器执行视图(或者至少它的行为方式是这样的)。如果您正在查看崩溃(未捕获的异常),则应该进行回滚。如果存储了一些数据,而没有存储一些数据,则您的数据库引擎可能不支持事务处理。

查看 django 文档以获取更多信息 https://docs.djangoproject.com/en/dev/ref/databases/

例如,如果您将 MySQL 与 MyISAM 一起使用,您可能会遇到一些问题

编辑: Krzysiek Szularz:我想每个人都在使用 django TransactionMiddleware 或类似的东西,所以我跳过了它——只提到了逻辑层。

于 2013-01-07T12:54:27.753 回答