Django:为什么我的“save_model()”不起作用?

时间:2010-12-22 01:41:20

标签: django forms save admin verification

如果有人可以帮助我弄清楚我的编码问题,我将非常非常感激。当我在管理界面中时,不会生成任何错误。但是,当我在管理界面下单击“保存”供应商对象时,我在自定义save_model(...)函数下指定的任何内容似乎都没有执行。我把我的代码压缩成了一些快照。 我做错了什么?

侧注:这可能听起来很奇怪,但我也试图在保存过程中删除该对象(它应该覆盖到另一个“提供者”对象,然后再这样做)。

===================

model.py

#models.py
...
class Provider(models.Model):  
  title = models.CharField(max_length=150)
  purpose = models.TextField()
  summary = models.TextField()
  email = models.EmailField()
  access_code = models.CharField(max_length=30, default=random_password)
  verified = models.BooleanField(default=False) #On/Off switch to display on database
  flagged = models.BooleanField(default=False) 
  revised = models.BooleanField(verbose_name = "New Update", default=False)
    # Will be True, if a revision has occured
        # On/Off switch state whether this is a revision of an existing Provider
    # This will be useful for creating a manager that lists updated providers
    # Note: Must delete Revised_Provider object after verification is complete
    # and UPDATE has occurred on save()

  #M2M Relations
  serviced_location = models.ManyToManyField(Location, through='ServicedLocations')
  services_offered = models.ManyToManyField(ServiceType, through='OfferedServices')
  insurances_accepted = models.ManyToManyField(InsuranceProvider, through='AcceptedInsurances')
  #contacts = models.ManyToManyField(Contact, blank=True)

  def __unicode__(self):
    return self.title

#Used for allow the provider to make change to their profile, and wait
#for verification before it will show up on regular search results
#Serves as a map for referencing a verified provider to a recent update (revision)
class Revision(models.Model): #Revised Providers (eg: Updated)
  provider = models.ForeignKey(Provider, null=True)
  date_revised = models.DateTimeField(auto_now=True, auto_now_add=True)
  def __unicode__(self):
      return u'%s' % self.provider

class ServicedLocations(models.Model):
  location = models.ForeignKey(Location)
  provider = models.ForeignKey(Provider) #Pre-Verified or Verified Settings
  revision = models.ForeignKey(Revision, null=True, on_delete=models.SET_NULL)
...etc...

===================

admin.py

#admin.py
from django.contrib import admin
from django.forms.models import ModelForm
from django import forms
from health.providers.models import *
class ProviderAdminForm(forms.ModelForm):
    def clean(self):
        cleaned_data = self.cleaned_data
        flagged = cleaned_data.get("flagged")
        verified = cleaned_data.get("verified")

        if flagged == True and verified == True:
        raise forms.ValidationError("You cannot verify a 'flagged' provider. If you meant to verify this provider, be sure to uncheck 'flagged'")
               # Just in case someone accidently verified a flagged provider       
        return cleaned_data

class ProviderAdmin(admin.ModelAdmin):    
    list_per_page = 100
    list_display = ('date_added', 'title', 'state', 'verified', 'flagged')
    list_display_links = ('title',)
    list_filter = ('verified', 'flagged', 'revised')
    search_fields = ['title',]
    filter_horizontal = ('services_offered',)
    form = ProviderAdminForm

    def save_model(self, request, obj, form, change):
        ProviderID = obj.id
        try: #see if a revision exists in the table
            Compare = Revision.objects.get(id=ProviderID)

            OldProviderID = Compare.provider.id
            OldProvider = Provider.objects.get(id=OldProviderID)

            RevisedProvider = Provider.objects.get(id=ProviderID) 
            RevisedProviderID = RevisedProvider.id

            if change:  #Check to see if we changed anything important
                verified = form.cleaned_data['verified']
                #Means we would have had to manually verified it

                if verified == True: 
                #This means that we have approved to update the old Provider
                #After copying the data over, we destroy what we are saving

                    obj.revised = False
                    obj.save()
                    #If we verfied it, revised = False  

                    OldProvider = RevisedProvider #Update Existing Provider Table
                    OldProvider.save()


                    NewLocations = ServicedLocations.objects.get(provider=RevisedProviderID)
                    OldLocations = ServicedLocations.objects.get(provider=OldProviderID)
                    OldLocations = NewLocations
                    OldLocations.save()
                    NewLocations.delete()


                    Compare.delete() #Delete from database
                    RevisedProvider.delete() #Delete Final Copy of Table

                    return HttpResponseRedirect("admin/providers/provider/%s/" % OldProviderID) #Redirect them to updated provider

        except Revision.DoesNotExist:
         print "This provider does not have any unverified revisions"

        return super(ProviderAdmin, self).save_model(request, obj, form, change)       

admin.site.register(Provider, ProviderAdmin)

2 个答案:

答案 0 :(得分:0)

代码在哪里丢失?你是说它根本不会执行 ?甚至不在第一行的日志语句?或者您是说在DB中没有进行预期的更改?

我尝试用各种理论重新创建你的情况但不能重现问题。你能更详细地描述问题是什么吗?尝试做一些pdb.set_trace(),挖掘并给我们一些更多细节:)

由于您没有提供例外,您需要提供有关错误的更多信息。

PS:我正在阅读您的代码,但很难阅读!类看起来像看起来像变量的实例......只是提出它违反了Python的编码约定,你可以看到语法高亮显示器认为你的CapitalizedObjects是类。


看起来您正在保存主对象,更改其引用的名称几次,然后再次保存,然后删除它!这里发生了非常令人困惑的事情...

这就是我所看到的......

RevisedProvider与obj的实例相同  RevisedProvider = Provider.objects.get(id=obj.id)

然后,将RevisedProvider分配给OldProvider,并在其上调用save(),这与obj(2次保存)的实例相同。

最后,删除RevisedProvider.delete(),这是您正在编辑的对象。

当我尝试重现该代码并删除我正在编辑的实例时,django会抛出ValidationError。

Sooo,我们需要更多信息来提供帮助。其他奇怪的地方在哪里?

答案 1 :(得分:0)

Yuji,

感谢您提供的建议,感谢您在查看我杂乱无章的编码方面的辛勤工作。

最初我的目标是在出现在公共搜索结果中之前,必须先验证(在管理界面中)提供商列表。我遇到的问题是,如果提供商更新了他们自己的联系信息,我们会自动设置verified = False(如果发布了不适当的内容)。因此,必须重新验证更新其信息的提供者,然后才能在数据库中出现。这很糟糕,因为它们会立即从搜索结果中删除。这就是为什么我引入了对我的数据库的修订,以便提供商可以随时编辑和更新他们的信息。现在,在我们手动验证提供商信息的更新版本之前,更改才会出现。

我想保持联系人的ID相同,以便记录历史记录保持不变。这太复杂了。因此,如果已验证的被选为True,那么最终只能在保存()时删除旧版本。

admin.py

def save_model(self, request, obj, form, change):
    providerid = obj.id
    if Revision.objects.filter(revised_provider=providerid).exists() and obj.revised == True:
        compare = Revision.objects.get(revised_provider=providerid)

        oldproviderid = compare.provider.id
        oldprovider = Provider.objects.get(id=oldproviderid)

        revisedproviderid = compare.revised_provider.id
        revisedprovider = Provider.objects.get(id=revisedproviderid) 


        if change:  #Check to see if we changed anything important
            verified = form.cleaned_data['verified']
            #Means we would have had to manually verified it

            if verified == True: 
            #This means that we have approved to update the old Provider
            #After copying the data over, we destroy what we are saving
                obj.revised = False
                obj.save()
                #If we verfied it, revised = False  

                compare.delete() #Delete Revision 
                oldprovider.delete() #Delete Old Provider

    return super(ProviderAdmin, self).save_model(request, obj, form, change)