正确使用GenericForeignKeys

时间:2013-08-22 04:35:38

标签: django

我正在尝试使用通用外键,但我似乎无法让它们正常工作。

首先,一些上下文:我有一个消息传递应用程序和一个组应用程序。现在,我希望能够让玩家/团体将pms(私人消息)写入其他用户/组。这是我的Pm模型:

class Pm(models.Model):
    """Represents a private message (a la email) from one user to another."""

    title = models.CharField(max_length=settings.max_title_length, default="(Blank)")
    slug = models.SlugField(max_length=settings.max_title_length, editable=False)

    #This was my code from when I only allowed pms to go from user to another
    #user
    #author = models.ForeignKey(Player, related_name="written_messages")
    #recipient = models.ForeignKey(Player, related_name="recieved_messages")
    text = models.TextField(max_length=settings.max_post_length)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()

    #Both will be either a group or a player
    author = generic.GenericForeignKey('content_type', 'object_id')
    recipient = generic.GenericForeignKey('content_type', 'object_id')
    #[snip]

这是我的小组和玩家模型的相关部分:

class Group(models.Model):
    #[snip]
    written_messages = generic.GenericRelation("messaging.Pm")
    sent_messages = generic.GenericRelation("messaging.Pm")

class Player(My_Model):
    user = models.OneToOneField(User)

    #[snip]
    written_messages = generic.GenericRelation("messaging.Pm")
    sent_messages = generic.GenericRelation("messaging.Pm")

这看起来是否正确?

当我运行它时,我得到了这个回溯(显然有些不对劲):

Traceback (most recent call last):
    File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 339, in urlconf_module
    return self._urlconf_module
AttributeError: 'RegexURLResolver' object has no attribute '_urlconf_module'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.2/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
File "/usr/local/lib/python3.2/dist-packages/django/contrib/staticfiles/handlers.py", line 72, in __call__
    return self.application(environ, start_response)
File "/usr/local/lib/python3.2/dist-packages/django/core/handlers/wsgi.py", line 180, in __call__
    self.load_middleware()
File "/usr/local/lib/python3.2/dist-packages/django/core/handlers/base.py", line 49, in load_middleware
    mw_instance = mw_class()
File "/usr/local/lib/python3.2/dist-packages/django/middleware/locale.py", line 24, in __init__
    for url_pattern in get_resolver(None).url_patterns:
File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 346, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/usr/local/lib/python3.2/dist-packages/django/core/urlresolvers.py", line 341, in urlconf_module
    self._urlconf_module = import_module(self.urlconf_name)
File "/usr/local/lib/python3.2/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
File "/home/mark/Dropbox/Public/Galcon/galcon/galcon/urls.py", line 40, in <module>
    ("^messages/", include("messaging.urls")),
File "/usr/local/lib/python3.2/dist-packages/django/conf/urls/__init__.py", line 26, in include
    urlconf_module = import_module(urlconf_module)
File "/usr/local/lib/python3.2/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/urls.py", line 3, in <module>
    from . import views
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/views.py", line 10, in <module>
    from . import my_forms
File "/home/mark/Dropbox/Public/Galcon/galcon/messaging/my_forms.py", line 5, in <module>
    class Modify_Message_Form(forms.ModelForm):
File "/usr/local/lib/python3.2/dist-packages/django/forms/models.py", line 283, in __new__
    raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (recipient) specified for Pm

上述表格非常简单:

class Modify_Message_Form(forms.ModelForm):
    class Meta:
        model = Pm
        fields = ["title", "recipient", "text"]

我做错了什么?谢谢!

2 个答案:

答案 0 :(得分:1)

在表单中使用GenericForeignKey的名称不起作用,因为它实际上不是真正的字段,而是更方便。没有小部件来显示关系;您通常会显示content_typeobject_id。如果您想在管理界面中查看关系,那么我建议您查看Grappelli

每个GenericForeignKey还需要content_typeobject_id个字段。

author_content_type = models.ForeignKey(ContentType)
author_object_id = models.PositiveIntegerField()

recipient_content_type = models.ForeignKey(ContentType)
recipient_object_id = models.PositiveIntegerField()

author = generic.GenericForeignKey('author_content_type', 'author_object_id')
recipient = generic.GenericForeignKey('recipient_content_type', 'recipient_object_id')

我对GenericRelations的经验不多,但据我所知,您还需要在content_typeobject_id模型中指定PlayerGroup字段

written_messages = generic.GenericRelation(messaging.Pm
                               content_type_field='author_content_type',
                               object_id_field='author_object_id')

答案 1 :(得分:1)

通过查看回溯,您似乎无法将GenericForeignKey用作表单字段。但我认为您可以使用recipient_content_typerecipient_content_id代替,这是Django管理员通常向用户展示的内容。