【问题标题】:Python Django - ForeignKey Class Choice for Model FieldPython Django - 模型字段的 ForeignKey 类选择
【发布时间】:2017-04-19 03:21:37
【问题描述】:

我想这样做,以便在创建和实例化模型时可以为字段模型/类选择外键。所以是这样的:

class Posts(models.Model):

    OwnerType = (
        (Accounts, 'User'),
        (Groups, 'Group'),
    )

    PostTypes = (
        ('Text', 'Text'),
        ('Photo', 'Photo'),
        ('Audio', 'Audio'),
        ('Video', 'Video'),
        ('Link', 'Link'),
    )

    owner = models.ForeignKey(OwnerType, default = 0, related_name = "post_owner")
    ownerid = models.IntegerField(blank = False, default = 0)
    owner_type = models.CharField(blank = False, default = '', max_length = 50)

    title = models.CharField(max_length = 500, default = '')
    contents = models.CharField(max_length = 500, default = '')
    attachment = models.CharField(max_length = 500, default = '')
    attachment_type = models.CharField(max_length = 500, default = '')
    link = models.CharField(max_length = 500, default = '')

    post_type = models.CharField(max_length = 20, choices = PostTypes, default = '')
    status = models.CharField(max_length = 20, default = 'public') # either public, private, or deleted

    date_created = models.DateField(auto_now_add=True)
    last_active = models.DateField(auto_now=True)

    @property
    def serialize(self):
        return {
            'p_id': self.id,

            'ownerid': self.ownerid,
            'owner': self.owner.serialize,
            'owner_type': self.owner_type,
            'title': self.title,
            'contents': self.contents,
            'attachment': self.attachment,
            'attachment_type': self.attachment_type,
            'link': self.link,
            'post_type': self.post_type,
            'status': self.status,
            'date_created': self.date_created,
            'last_active': self.last_active
        }

    class Meta:
        db_table = "posts"

# ---

然后我得到这个错误:

    Traceback (most recent call last):
  File "manage.py", line 9, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 327, in execute
    django.setup()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/RyanWaite/Desktop/epsity/webapp/models.py", line 320, in <module>
    class Posts(models.Model):
  File "/Users/RyanWaite/Desktop/epsity/webapp/models.py", line 335, in Posts
    owner = models.ForeignKey(OwnerType, default = 0, related_name = "post_owner")
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/related.py", line 754, in __init__
    RECURSIVE_RELATIONSHIP_CONSTANT,
AssertionError: ForeignKey(((<class 'webapp.models.Accounts'>, u'User'), (<class 'webapp.models.Groups'>, u'Group'))) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string u'self'

这可能吗?创建模型的新实例时,我可以为外键选择模型吗?我有两种可以发帖的模型:用户和组。用户可以发帖,或者群组可以发帖。

【问题讨论】:

    标签: python django django-models django-orm


    【解决方案1】:

    所以这是我的自定义方法:

    我添加了 type 和 type_id 字段,其中 type 是 Model Class 的字符串。 然后我创建了一个函数,它将根据给定的参数返回模型实例。例如。 :

    def returnModelSerialized(type, id):
        if id == None:
            return 'error --- Missing id'
    
        if type == '' or Type == None:
            return 'error --- invalid type'
    
        if type == 'Account':
            obj = Accounts.objects.get(id = id)
            return obj.serialize
    
        if type == 'Group':
            obj = Groups.objects.get(id = id)
            return obj.serialize
    

    所以当我调用一个序列化属性方法时,它看起来像这样:

    class Likes(models.Model):
    
    OwnerType = (
        ('Account', 'Account'),
        ('Group', 'Group'),
    )
    
    ContentType = (
        ('Post', 'Post'),
        ('Comment', 'Comment'),
        ('Reply', 'Reply'),
        ('Group', 'Group'),
        ('Event', 'Event'),
    )
    
    ownerid = models.IntegerField(blank = False, default = 0)
    owner_type = models.CharField(choices = OwnerType, blank = False, default = '', max_length = 50)
    
    item_type = models.CharField(choices = ContentType, blank = False, default = '', max_length = 50)
    item_id = models.IntegerField(blank = False, default = 0)
    
    date_created = models.DateField(auto_now_add=True)
    last_active = models.DateField(auto_now=True)
    
    @property
    def serialize(self):
        return {
            'like_id': self.id,
    
            'ownerid': self.ownerid,
            'owner': returnModelSerialized( self.owner_type , self.ownerid ),
            'owner_type': self.owner_type,
            'item_type': self.item_type.serialize,
            'item_id': self.item_id,
            'date_created': self.date_created,
            'last_active': self.last_active
        }
    
    class Meta:
        db_table = "likes"
    

    【讨论】:

      【解决方案2】:

      来自文档doc

      普通的 ForeignKey 只能“指向”另一个模型,这意味着如果 TaggedItem 模型使用 ForeignKey,则必须选择一个且只有一个模型来存储标签

      您可以使用GenericForeignKey,它允许与任何模型建立关系

      【讨论】:

      • 谢谢!我实际上找到了解决这个问题的方法。我只是使用了类型和类型 id 字段,然后创建了一个函数,该函数将根据给定的参数返回模型实例。谢谢!
      猜你喜欢
      • 2018-03-01
      • 2021-07-13
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 2017-12-15
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      相关资源
      最近更新 更多