在Django中获取或创建通用关系及Python调试一般问题

6 投票
2 回答
2814 浏览
提问于 2025-04-15 21:37

我运行了这个示例中的代码,目的是创建一些通用相关的对象: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本身就比较复杂,所以多尝试、多阅读文档和源代码是非常有帮助的。

撰写回答