1. Codeboy.ru

    25.03.2010

    0 ↑
    0 ↓
    Есть крайне насущные вопросы, просто [color=grey]ужас какие важные[/color] для меня.
    Есть модель (очень простой пример)
    class Foo(models.Model):
    name = models.CharField(max_length=20)
    ...
    Category = models.ForeignKey('Category')

    class Category(models.Model):
    name = models.CharField(max_length=20)

    # второй вопрос
    class Category(models.Model):
    name = models.CharField(max_length=20)
    parent = models.ForeignKey(self)

    # третий вопрос
    class Foo(models.Model):
    name = models.CharField(max_length=20)
    date_time = models.DateTimeField(
    'Date Published', auto_now = True, auto_now_add=True)
    [color=red]1.[/color] Мне надо, что бы можно было тип "category" не задавать при желании, типа blank=True, т.е. поле не обязательное было.
    [color=red]2.[/color] Надо построить самую простую иерархию (на 100-500 итемов при глубине 2-3). Когда я пытаюсь добавить первый тип мне кидают отлуп - "не задано поле parent", а как я его задам??? и при добавлении следующего обьекта мне например нужно поставить первый (вернее нулевой уровень), а не получится.
    Отсюда вопрос - как сделать такую иерархию? Собственно оба вопроса связаны как понятно из кода.
    [color=red]3.[/color] когда я для поля date_time ставлю авто добавление сегодняшней даты то у меня блокируется возможность менять её - как редактировать дату?
    [color=green]C[/color]кажу сразу - я новичок пока и в питоне и в джанго, но приму любые ответы, даже ссылки, а то читаю маны уже второй день а воз и ныне там!
    Спасибо заранее.
  2. truetug.ya.ru

    25.03.2010

    0 ↑
    0 ↓
    • Category = models.ForeignKey('Category', null=True, blank=True)
    • Для создания иерархических структур лучше пользоваться специальными приложениями для этого, где уже решены 100500 вопросов, например «как выбрать всех потомков определенной ветки» или «как вывести дерево в select».
    • Во-первых auto_now и auto_now_add вместе не используют, потому что auto_now меняется при каждом изменений модели, а auto_now_add только при создании записи, во-вторых auto_now и auto_now_add сейчас не модно делать, модно менять метод save модели:
      def save(self):
      if not self.pk:
      self.created= datetime.now() # Вместо auto_now_add

      self.modified = datetime.now() # Вместо auto_now

      super(Category, self).save()
    Пройдите туториал, посмотрите как сделан сайт джанги.
  3. admin

    25.03.2010

    1 ↑
    0 ↓
    1
    class Foo(models.Model):
    name = models.CharField(max_length=20)
    ...
    category = models.ForeignKey('Category', related_name='foos',
    blank=True, null=True)
    2
    class Category(models.Model):
    name = models.CharField(max_length=20)
    parent = models.ForeignKey('self', blank=True, null=True)
    обратите внимание на то, что 'self' в кавычках. это строковый идентификатор, распознаваемый models.ForeignKey, а не переменная.
    3
    class Foo(models.Model):
    name = models.CharField(max_length=20)
    date_time = models.DateTimeField('Date Published',
    auto_now_add=True)

    если с категориями предстоит работать как с деревьями, то используйте готовое решение http://code.google.com/p/django-mptt/ .
  4. Alexander Koval

    25.03.2010

    0 ↑
    2 ↓
    Вот с деревьями не все так гладко в django:

    django-mptt как на мой взгляд сделан коряво. Нафига спрашивается нужен этот register(), если можно сделать нормальное наследование? Например из-за этого оно не работает с south.

    django-treebeard - лицензия Apache License (насколько я понял требующая сообщать автору где вы используете его код, если ошибаюсь поправьте).

    Я пользуюсь своей библиотекой для построения деревьев, на основе nested sets, но в ней есть несколько проблем, например, есть проблема гонок, так как мне влом было писать чистый SQL, а select for update в django нет.
  5. django-mptt как на мой взгляд сделан коряво. Нафига спрашивается нужен этот register(), если можно сделать нормальное наследование? Например из-за этого оно не работает с south.

    В защиту django-mptt скажу, что оно появилось ещё в те времена, когда никого наследования и уж тем более South не было и в помине. И менять архитектуру сейчас, там самым ломая совместимость, накладно.

    django-treebeard - лицензия Apache License (насколько я понял требующая сообщать автору где вы используете его код, если ошибаюсь поправьте).

    Вы ошибаетесь.

  6. admin

    26.03.2010

    0 ↑
    1 ↓
    своей библиотекой для построения деревьев, на основе nested sets
    вот любопытная статья http://www.dbazine.com/oracle/or-articles/tropashko4 где описаны несколько вариантов представления деревьев в rdb. обратите внимание на nested intervals, как обобщение nested sets. этот способ представления имеет определенные преимущества. например, при вставке узла в NI не нужно пересчитывать ключ для всех узлов справа.
  7. Alexander Koval

    26.03.2010

    0 ↑
    0 ↓
    В защиту django-mptt скажу, что оно появилось ещё в те времена, когда никого наследования и уж тем более South не было и в помине. И менять архитектуру сейчас, там самым ломая совместимость, накладно.
    Это говорит о том, что автор давно забил на развитие django-mptt. А дописать можно и не ломая совместимость: просто оставить register() и сделать абстрактную модель.
  8. Codeboy.ru

    31.03.2010

    0 ↑
    0 ↓
    Спасибо за ответы, ссори что сразу не ответил - коммандировка.

    Для категорий нужно решении с минимальными затратами, что-то большее чем child-parent смысла нет для небольших таблиц (100-250 полей при 10-15 категорий 1-3 вложенности).
    Хотелось бы что-то вроде - "Materialized Path"
    fields = ('child', 'parents', 'level',)
    отсюда пример
    id(child) = 15
    parents = 0106
    level = 2
    Тогда выборка всех родителей второго уровня (0106) будет типа
    SELECT from 'table' * WHERE 'parents'= 0106
    Пока самой простой кажется запись как у "admin" ))
    class Category(models.Model):
    name = models.CharField(max_length=20)
    parent = models.ForeignKey('self', blank=True, null=True)

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.