2016-12-04 5 views
1

Я хочу сделать так, чтобы я мог выбрать внешний ключ для модели поля/класса при создании и экземпляре модели. Так что-то вроде этого:Python Django - ForeignKey Class Choice для поля модели

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' 

Является ли это вообще возможно? Могу ли я выбрать модель для внешнего ключа при создании нового экземпляра модели? У меня есть два типа моделей, которые могут создавать сообщения: пользователи и группы. пользователь может сделать сообщение, или группа может сделать сообщение.

ответ

1

из документации doc

A normal ForeignKey can only “point to” one other model, which means that if the TaggedItem model used a ForeignKey it would have to choose one and only one model to store tags for

Вы можете использовать GenericForeignKey, что позволяет отношения быть с любой моделью

+0

Спасибо! Я действительно нашел свой собственный путь вокруг этого. я просто использовал поля типа и типа id, а затем создал функцию, которая вернет экземпляр модели на основе данных параметров. Благодаря! – ryanwaite28

0

Так вот мой пользовательский путь вокруг этого:

я добавил тип и TYPE_ID поля, где type - строка класса модели. , тогда я создал функцию, которая вернет экземпляр модели на основе заданных параметров. напр. :

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" 
Смежные вопросы