Django:为什么我的“save_model()”是不工作?
如果有人能帮助我解决我的编码问题,我将非常非常感激。当我进入管理界面时,不会生成任何错误。但是,当我在管理界面下单击 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)
I will be very, VERY grateful if someone can help me figure out my coding problem. When I'm in the admin interface, no errors are generated. However, nothing that I specify under my custom save_model(...) function seems to execute when I click "Save" for a Provider object under the admin interface. I've condense my code down into little snap shots. What am I doing wrong?
Side Note: This may sound strange, but I'm also trying to delete the object during the save process (it's supposed to overwrite to another "provider" object before doing so).
===================
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Yuji,
谢谢你的提示,我很感谢你为调查我杂乱的编码所做的辛勤工作。
最初我的目标是拥有一个必须在出现在公共搜索结果中之前(在管理界面中)进行验证的提供商列表。我遇到的问题是,如果提供商更新了自己的联系信息,我们会自动设置verified=False(以防发布不适当的内容)。因此,更新信息的提供商在出现在数据库中之前必须经过重新验证。这太糟糕了,因为它们会立即从搜索结果中删除。这就是为什么我对数据库进行了修订,以便提供商可以随时编辑和更新他们的信息。现在,直到我们手动验证提供商信息的更新版本后,新的更改才会出现。
我希望保持联系人的 ID 不变,以便日志记录历史记录保持不变。这变得太复杂了。因此,如果 verified 被检查为 True,它就会在 save() 时删除旧版本。
管理员.py
Yuji,
Thank-you for your tips, and I appreciate your hard work at looking into my disorganized coding.
Originally my goal was to have a list of Providers that had to be verified (in the admin interface) before appearing in the public search results. The problem I encountered was that if a Provider updated their own contact information, we automatically set verified=False (in case something inappropriate was posted). So, a Provider who updated their information would then have to be reverified before appearing at all on the database. This was awful, because they would instantly be removed from the search results. That's why I introduced revisions to my database, so that a provider could edit and update their information at anytime. Now the new changes just wouldn't appear until we manually verified updated version of the Provider's information.
I wanted to keep the ID of the contact the same, so that logging history would remain the same. This became too complicated. So, just ended up making it so that it'd delete the old version upon a save() if verified was checked as True.
admin.py
代码在哪里抛出?您是说它根本不会执行吗?甚至不在第一行记录语句?或者您是说数据库中没有进行预期的更改?
我尝试用各种理论重现您的情况,但无法重现问题。您能更详细地描述一下问题是什么吗?尝试执行一些 pdb.set_trace(),深入研究并向我们提供更多详细信息:)
由于您没有提供异常,因此您需要提供有关错误的更多信息。
PS:我正在阅读你的代码,但它很难阅读!类看起来像实例,又像变量……请注意,它违反了 Python 的编码约定,正如您可以通过语法荧光笔看到的那样,认为您的 CapitalizedObjects 是类。
看起来您正在保存主对象,更改其引用名称几次,然后再次保存,然后删除它!这里发生的事情非常令人困惑...
这就是我所看到的...
RevisedProvider 与 obj 是相同的实例。
RevisedProvider = Provider.objects.get(id=obj.id)
然后,将 ReviedProvider 分配给 OldProvider,并对其调用
save()
,这与以下实例相同obj(保存 2 次)。最后,您删除
RevisedProvider.delete()
,这是您正在编辑的对象。当我尝试重现该代码并删除我正在编辑的实例时,django 会抛出 ValidationError。
Sooo,我们需要更多信息来提供帮助。其他奇怪的地方在哪里?
Where does the code poop out? Are you saying it won't execute at all? not even log statements on the first line? or are you saying your expected changes are not being made in the DB?
I've tried recreating your situation with various theories but can't reproduce a problem. Can you describe in more detail what the problem is? Try doing some pdb.set_trace(), dig around and give us some more details : )
Since you haven't provided an exception, you need to provide more information about what's wrong.
PS: I'm reading through your code but it's very hard to read! Classes look like instances which look like variables... Just a heads up it goes against coding conventions for Python as you can see with the syntax highlighter thinking your CapitalizedObjects are classes.
It looks like you are saving the main object, changing its referenced name a few times and then saving it again, then deleting it! Very confusing stuff going on here...
Here's what I see...
RevisedProvider is the same instance as obj.
RevisedProvider = Provider.objects.get(id=obj.id)
Then, you assign RevisedProvider to OldProvider, and call
save()
on that, which is the same instance as obj (2 saves).At the end, you delete
RevisedProvider.delete()
, which is the object you are editing.When I try to reproduce that code, and delete the instance I'm editing, django throws a ValidationError.
Sooo, we need more information to help. Where are the other oddities?