2014-05-24 4 views
1

Я создаю приложение с динамическими моделями (следующие рекомендации [1]) для создания интерфейса для уже существующей базы данных.Первичный ключ в динамической модели

Это моя функция, чтобы создать одну из моделей (на самом деле он имеет больше полей и прочее, но это должно быть достаточно):

def create_model(name): 
    # Meta class 
    class Meta: 
     pass 

    # Set up a dictionary to simulate declarations within a class 
    attrs = {'__module__': 'mymodule', 
      'Meta': Meta, 
      'fields': { 
       'myID': models.CharField(max_length=2, db_column='myID', primary_key=True), 
       '__unicode__': lambda self: self.myID, 
       } 
      } 

    # Create the class, which automatically triggers ModelBase processing 
    model = type(name, (models.Model,), attrs) 

    admin.site.register(model, admin.ModelAdmin) 

    return model 

Но когда я пытаюсь получить доступ к этой модели я получаю следующее OperationalError:

(1054, "Unknown column 'database_table.id' in 'field list'") 

кажется, что Django не принимая во внимание моего prymary_key определения для поля myID и это создает параметр по умолчанию id поля.

Я что-то упустил? Это «ошибка», связанная с созданием динамической модели? Кто-нибудь знает обходное решение для этого? Благодаря

[1] https://code.djangoproject.com/wiki/DynamicModels

ответ

3

Ваши поля и методы не должны быть в пределах 'fields' словаря в вашем attrs, но должно быть на высшем уровне attrs Dict.

Это:

attrs = {'__module__': 'mymodule', 
     'Meta': Meta, 
     'fields': { 
      'myID': models.CharField(max_length=2, db_column='myID', primary_key=True), 
      '__unicode__': lambda self: self.myID, 
      } 
     } 

функционально эквивалентно следующему:

class MyModel(models.Model): 
    class Meta: 
     pass 

    fields = { 
     'myID': models.CharField(max_length=2, db_column='myID', primary_key=True), 
     '__unicode__': lambda self: self.myID, 
     } 

    def __unicode__(self): 
     return self.myID 

ModelBase метаклассом принимает любое поле (на самом деле любой объект с методом contribute_to_class), который определен на верхнем уровне класса и использует метод contribute_to_class в поле, чтобы «добавить» его к фактическому классу. В этом процессе поле добавляется в словарь fields, но вы не должны определять словарь полей перед запуском реального метакласса. Ваш attrs должен выглядеть следующим образом, вместо:

attrs = {'__module__': 'mymodule', 
     'Meta': Meta, 
     'myID': models.CharField(max_length=2, db_column='myID', primary_key=True), 
     '__unicode__': lambda self: self.myID, 
     } 
+0

Спасибо! После прочтения вашего ответа я вернулся к своей ссылке (см. [1] выше), чтобы проверить, было ли это ошибкой, и я только что понял, что он делает именно то, что вы говорите: 'attrs.update (поля)' Я реализовал это неправильно ... – jgsogo

2

Я строй приложения с помощью динамических моделей (следующих руководящих принципов [1]), чтобы создать интерфейс для уже существующей базы данных.

Вы уверены, что это правильный подход? Вы не хотите использовать manage.py inspectdb для создания моделей из этой базы данных? См .:

https://docs.djangoproject.com/en/dev/howto/legacy-databases/

+0

Я не знал о команде 'inspectdb' (facepalm). Это было бы очень полезной отправной точкой, но теперь уже поздно:/ Во всяком случае, мне нравится динамический подход, потому что у меня есть много моделей с именами и полями на основе идентификаторов языков (EngVariant, SpaVariant, ...) и таким образом Я придерживаюсь принципа СУХОЙ. – jgsogo

Смежные вопросы