Как написать этот класс для модели данных Django (преобразование из формата YML Propel) - PullRequest
1 голос
/ 05 октября 2010

Я преобразую веб-проект, который в настоящее время использует Propel ORM , в проект django.

Моя первая задача - «перенести» схему модели на django.

Я прочитал django docs, но, похоже, они не достаточно подробны.Например, как мне «портировать» (надуманную) таблицу, определенную в схеме Propel YML, следующим образом:

  demo_ref_country:
    code:             { type: varchar(4), required: true, index: unique }
    name:             { type: varchar(64), required: true, index: unique }
    geog_region_id:   { type: integer, foreignTable: demo_ref_geographic_region, foreignReference: id, required: true, onUpdate: cascade, onDelete: restrict }
    ccy_id:           { type: integer, foreignTable: demo_ref_currency_def, foreignReference: id, required: true, onUpdate: cascade, onDelete: restrict }
    flag_image_path:  { type: varchar(64), required: true, default: ''}
    created_at: ~

    _indexes:

      idx_f1:         [geog_region_id, ccy_id, created_at]

    _uniques:

      idxu_f1_key:    [code, geog_region_id, ccy_id]

Вот моя (слабая) попытка на данный момент:

class Country(models.Model):
    code = models.CharField(max_length=4)  # Erm, no index on this column .....
    name = models.CharField(max_length=64) # Erm, no index on this column .....
    geog_region_id = models.ForeignKey(GeogRegion)  # Is this correct ? (how about ref integrity constraints ?
    ccy_id = models.ForeignKey(Currency) # Is this correct?
    flag_image_path = models.CharField(max_length=64) # How to set default on this col?
    created_at = models.DateTimeField()    # Will this default to now() ?
    # Don't know how to specify indexes and unique indexes ....

[Редактировать]

Всем, кто предлагает мне RTFM, я понимаю ваше разочарование.Просто документация мне не очень понятна.Это, вероятно, Pythonic способ документирования - но, исходя из фона C ++, я чувствую, что документация может быть улучшена, чтобы сделать ее более доступной для людей, говорящих на разных языках.

Пример: в документации просто говорится оИмя класса и параметр ** параметров в ctor, но не говорит вам, каковы возможные параметры.

Например, класс CharField (max_length = None, [** options])

В документации есть строка, которая содержит список допустимых опций, применимых ко всем полямtypes.

Однако параметры предоставляются в виде:

Field.optionname

(очевидно неявная) связь между свойством класса и аргументом конструктора не яснамне.Похоже, что если у класса есть свойство foo, это означает, что вы можете передать аргумент с именем foo его конструктору.Это наблюдение верно для всех классов Python?

Ответы [ 5 ]

1 голос
/ 05 октября 2010
code = models.CharField(max_length=4)  # Erm, no index on this column .....
name = models.CharField(max_length=64) # Erm, no index on this column .....

Вы можете передать аргумент и значение ключевого слова unique = True для обоих вышеперечисленных.

geog_region_id = models.ForeignKey(GeogRegion)  # Is this correct ? (how about ref integrity constraints ?
ccy_id = models.ForeignKey(Currency) # Is this correct?

Вышеуказанные строки верны , если GeogRegion и Currency определены до этой модели. В противном случае ставьте кавычки вокруг названий моделей. Например, models.ForeignKey("GeogRegion"). См. документацию .

flag_image_path = models.CharField(max_length=64) # How to set default on this col?

Easy. Используйте аргумент и значение ключевого слова default = "/foo/bar".

created_at = models.DateTimeField()    # Will this default to now() ?

Не автоматически. Вы можете сделать default = datetime.now (не забудьте сначала from datetime import datetime). Также вы можете указать auto_now_add = True.

# Don't know how to specify indexes and unique indexes ....

Взгляните на unique_together.

Вы увидите, что документ, на который я ссылался, тот же, на который указали другие. Я настоятельно призываю вас прочитать документы и пройти обучение по .

1 голос
/ 05 октября 2010

Извините, вы не читали документы.Простой поиск index, unique или default на справочной странице показывает, как именно установить эти параметры.

Редактировать после комментария Iне понимаю, что вы имеете в виду о нескольких строках.Python не заботится о том, сколько строк вы используете в квадратных скобках - вот что:

name = models.CharField(unique=True, db_index=True)

точно так же, как это:

name = models.CharField(
          unique=True,
          db_index=True
       )

Django не поддерживает первичную многостолбцовую системуклавиш, но если вы просто хотите использовать уникальное ограничение из нескольких столбцов, см. unique_together .

1 голос
/ 05 октября 2010
import datetime
class Country(models.Model):
    code = models.CharField(max_length=4, unique=True) 
    name = models.CharField(max_length=64)
    geog_region = models.ForeignKey(GeogRegion)  
    ccy = models.ForeignKey(Currency, unique=True)
    flag_image_path = models.CharField(max_length=64, default='') 
    created_at = models.DateTimeField(default=datetime.now())

(я не специалист по орпелу)

Django всегда пытается имитировать поведение «каскад при удалении», поэтому нет необходимости указывать это где-либо. По умолчанию все поля обязательны для заполнения, если не указано иное. Для поля даты и времени см. Еще несколько опций здесь . Все общие параметры поля здесь .

1 голос
/ 05 октября 2010

Индексы автоматически создаются для ваших ссылок на другие модели (т.е. ваши внешние ключи). Другими словами: ваш geog_region_id правильный (но было бы лучше назвать его geog_region).

Вы можете установить значения по умолчанию, используя параметр поля по умолчанию .

0 голосов
/ 05 октября 2010
Class demo_ref_country(models.Model)
    code= models.CharField(max_length=4, db_index=True, null=False)
    name= models.CharField(max_length=64, db_index=True, null=False)
    geog_region = models.ForeignKey(geographic_region, null=False)
    ccy = models.ForeignKey(Currency_def, null=False)
    flag = models.ImageField(upload_to='path to directory', null=False, default="home")
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

class Meta:
    unique_together = (code, geog_region, ccy)

Вы можете установить значения по умолчанию. Параметр db_index создает индексы для связанных полей. Вы можете использовать unique = True для отдельных полей, но tahat unique вместе проверит уникальность в столбцах вместе.

ОБНОВЛЕНИЕ: Прежде всего, я советую вам внимательно прочитать документацию, поскольку django дает вам много возможностей, некоторые из них имеют некоторые ограничения ... Например, опция unique_together используется только для админ django Это означает, что если вы создаете новую запись или редактируете ее через интерфейс администратора, она будет использоваться. Если вы также будете вставлять данные другими способами (например, оператором DataModel.objects.create), лучше использовать uniaue = True в определении поля, например:

code= models.CharField(max_length=4, db_index=True, null=False, unique=True)

Поля ForeignKey по умолчанию уникальны, поэтому вам не нужно определять для них уникальность.

Django поддерживает переопределение методов, поэтому вы можете переопределять методы сохранения и удаления моделей по своему усмотрению. проверьте это здесь . Django также позволяет вам писать необработанные SQL-запросы , вы можете проверить это здесь

Как я объяснил, вместе взятые - это админка django. Так что не забудьте добавить unique = True в обязательные поля. Unique вместе также позволяет вам определять различные уникальные пары, такие как;

unique_together = (('id','code'),('code','ccy','geog_region'))

Это означает, что id и код должны быть уникальными вместе и code, ccy и geog_region должны быть уникальными вместе

ОБНОВЛЕНИЕ 2: до обновления вашего вопроса ...

Лучше начать с учебников . Это определяет основы с хорошими примерами.

Что касается стиля doc, позвольте мне привести вам пример, но если вы начнете с репетиторов, вам будет легче ... Есть из структуры модели ... Док здесь

BooleanField

class BooleanField(**options)

, который определяет, используется базовая структура поля базы данных (), и некоторые параметры взяты в качестве опций. это часть:

models.BooleansField()

Поскольку это структура поля, доступные параметры определяются следующим образом:

unique

Field.unique

Итак,

models.BooleansField(unique=True)

Это общее использование. Поскольку uniqu - это базовая опция, доступная для всех типов полей, она классифицируется как field.unique. Есть несколько параметров, доступных для одного типа поля, например, симметричный, который является параметром поля ManyToMany, классифицируется как ManyToMany.Symmetrical

Для queryset

class QuerySet([model=None])

Используется при использовании функции, но вы используете ее для фильтрации модели, другими словами, пишите запрос фильтра для выполнения ... У него есть несколько методов, например, фильтр ...

filter(**kwargs)

Поскольку для этого требуются некоторые kwargs, и, как я уже говорил, это используется для фильтрации результатов вашего запроса, поэтому kwargs должны быть полями вашей модели (полями таблицы базы данных) Как:

MyModel.objects.filter(id=15)

что за объект определяется в документе, но это менеджер, который помогает вам получать связанные объекты.

Док содержит хорошие примеры, но вы должны начать с репетиторов, вот что я могу вам посоветовать ...

...