0

I'm trying to use generic foreign keys, but I can't seem to get them to work properly.

First, some context: I've got a messaging app and a groups app. Now, I want to be able to have players/groups write pms (private messages) to other users/groups. Here's my Pm model:

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]

and here's the relevant bits of my Group and Player models:

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")

Does this look correct?

When I run it, I get this traceback (so obviously something's wrong):

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

The mentioned form is pretty simple:

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

What have I done wrong? Thanks!

4

2 回答 2

1

Using the name of the GenericForeignKey in the form doesn't work as it's not actually a real field but more of a convenience. There's no widget to display the relationship; you usually display the content_type and object_id. If you want to see the relationship in the admin interface then I'd recommend looking at Grappelli.

You also need content_type and object_id fields for each GenericForeignKey.

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')

I've not much experience with GenericRelations but from what I know you'd also need to specify the content_type and object_id fields in your Player and Group models.

written_messages = generic.GenericRelation(messaging.Pm
                               content_type_field='author_content_type',
                               object_id_field='author_object_id')
于 2013-08-22T05:35:57.140 回答
1

It seems, by looking at the traceback, that you cannot use GenericForeignKeys as form fields. But I think you can use recipient_content_type and recipient_content_id instead, which is what Django admin usually shows to users.

于 2013-08-22T07:20:54.780 回答