在Django中获取或创建通用关系及Python调试一般问题
我运行了这个示例中的代码,目的是创建一些通用相关的对象:http://www.djangoproject.com/documentation/models/generic_relations/
一开始一切都很好:
>>> bacon.tags.create(tag="fatty")
<TaggedItem: fatty>
>>> tag, newtag = bacon.tags.get_or_create(tag="fatty")
>>> tag
<TaggedItem: fatty>
>>> newtag
False
但是接下来,我想在我的应用中实现的用例是:
>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 123, in get_or_create
return self.get_query_set().get_or_create(**kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 343, in get_or_create
raise e
IntegrityError: app_taggeditem.content_type_id may not be NULL
我在看了其他代码后尝试了很多随机的方法:
>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome", content_type=TaggedItem)
ValueError: Cannot assign "<class 'generics.app.models.TaggedItem'>": "TaggedItem.content_type" must be a "ContentType" instance.
或者:
>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome", content_type=TaggedItem.content_type)
InterfaceError: Error binding parameter 3 - probably unsupported type.
等等。
我相信有人能告诉我正确的语法,但真正的问题是我完全不知道发生了什么。我在强类型语言(像x86汇编、C++和C#)中开发了超过十年,但对Python还是个新手。当像这样的错误出现时,我发现很难理解Python中的情况。
在我之前提到的那些语言中,搞清楚这些事情相对简单——只需检查方法的签名和参数。而我花了半个小时看Django的文档,结果还是一头雾水。查看get_or_create(self, **kwargs)的源代码也没什么帮助,因为没有方法签名,代码看起来非常通用。接下来的步骤是调试这个方法,试着弄明白发生了什么,但这似乎有点过于极端了……
我感觉自己在这里缺少一些基本的操作原则……这是什么呢?将来我该如何独立解决类似的问题?
2 个回答
2
我这里收集了一些关于Django调试的链接。其中最好的两个是Simon Willison的文章(特别是pdb,如果你是从C#/VisualStudio背景过来的,这个可能会让你觉得更熟悉一些)和Django调试工具栏。
10
ContentType.objects.get_for_model()
这个方法可以帮你找到一个模型对应的合适的 ContentType
。你只需要把这个返回的对象当作 content_type
使用就可以了。
而且在学习Django的时候,不用太担心自己能不能理解。Django本身就比较复杂,所以多尝试、多阅读文档和源代码是非常有帮助的。