【问题标题】:Django: Why is my "save_model()" not working?Django:为什么我的“save_model()”不起作用?
【发布时间】:2010-12-22 01:41:19
【问题描述】:

如果有人能帮我解决我的编码问题,我将非常非常感激。当我在管理界面中时,不会产生任何错误。但是,当我在管理界面下为 Provider 对象单击“保存”时,我在自定义 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)

【问题讨论】:

    标签: django forms save admin verification


    【解决方案1】:

    代码在哪里弹出?你是说它根本不会执行?甚至没有在第一行记录语句?或者您是说数据库中没有进行您预期的更改?

    我尝试用各种理论重现您的情况,但无法重现问题。你能更详细地描述问题是什么吗?尝试做一些 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,我们需要更多信息来提供帮助。其他的怪事在哪里?

    【讨论】:

    • 谢谢 :-) 请看我上面的评论
    【解决方案2】:

    虞姬,

    感谢您的提示,感谢您为调查我杂乱无章的编码所做的辛勤工作。

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

    我想保持联系人的 ID 不变,以便记录历史记录保持不变。这变得太复杂了。所以,刚刚完成它,如果 verified 被检查为 True,它会在 save() 时删除旧版本。

    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)      
    

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 1970-01-01
      • 2021-01-18
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2021-12-07
      • 2020-01-19
      相关资源
      最近更新 更多