Как создать экземпляры связанных моделей в Django - PullRequest
3 голосов
/ 20 марта 2010

Я работаю над приложением CMSy, для которого я реализовал набор моделей, которые позволяют создавать пользовательские экземпляры Template, состоящие из нескольких полей и привязанные к конкретному клиенту.Конечной целью является то, что один или несколько шаблонов с набором настраиваемых полей могут быть определены через интерфейс администратора и связаны с клиентом, чтобы клиент мог затем создавать объекты содержимого в формате, заданном шаблоном.

Я, кажется, получил это подключено так, что я могу создавать любое количество объектов Template, но я борюсь с тем, как создавать экземпляры - фактические объекты содержимого - в этих шаблонах.Например, я могу определить шаблон «Базовая страница» для клиента «Acme», который имеет поля «Заголовок» и «Тело», но я не выяснил, как создавать экземпляры Базовой страницы, где эти поля можно заполнять.

Вот мои (несколько элитные) модели ...

class Customer(models.Model):
    ...

class Field(models.Model):
    label = models.CharField(max_length=255)
    component = models.ForeignKey(ContentType, 
            limit_choices_to={'id__in': component_choices}
            )
    fields = models.Manager()

class Template(models.Model):
    label = models.CharField(max_length=255)
    clients = models.ManyToManyField(Customer, blank=True)
    fields = models.ManyToManyField(Field, blank=True)

class ContentObject(models.Model):
    label = models.CharField(max_length=255)
    template = models.ForeignKey(Template)
    author = models.ForeignKey(User)
    customer = models.ForeignKey(Customer)
    mod_date = models.DateTimeField('Modified Date', editable=False)
    def __unicode__(self):
        return '%s (%s)' % (self.label, self.template)
    def save(self):
        self.mod_date = datetime.datetime.now()
        super(ContentObject, self).save()

Заранее благодарен за любой совет!

Ответы [ 4 ]

1 голос
/ 20 марта 2010

Если вы хотите придерживаться этой модели архитектуры, вам нужно добавить еще одно поле в класс ContentObject, который будет служить для хранения фактического содержимого. Это может быть что-то вроде:

ContentObject(models.Model):
    ...
    fields_content = models.ManyToManyField(Field, through=FieldContent)
    ...

и затем:

class FieldContent(models.Model):
    field = ForeignKey(Field)
    content_object = ForeignKey(ContentObject)
    content = CharField

Тогда вам, очевидно, следует убедиться, возможно, используя сигнал pre_save, что для данного экземпляра ContentObject только поля, которые находятся в шаблоне экземпляра, могут перейти в таблицу FieldContent.

А затем вы можете создать фактический контент, например:

FieldContent.objects.create(field=your_field, content_object=your_content_object, content=content_given_by_the_customer)
0 голосов
/ 30 марта 2010

Чтобы расширить ответ pawartur, есть несколько способов обработки нескольких (возможно сложных) типов данных для полей. Один из способов, которым вы можете попытаться, - это использовать наследование модели, возможно, что-то вроде этого:

class FieldContent(models.Model):
    field = models.ForeignKey(Field)
    content_object = models.ForeignKeyKey(ContentObject)
    def get_component(self):
        """Return the specific component instance for this field."""
        return self.field.get_object_for_this_type(pk=self.pk)

Затем вы наследуете от этой базовой модели для каждого компонента типа поля, например:

class SomeComponent(FieldContent):
    # specific fields for the component here

Затем вы можете делать такие вещи, как: somecontentobject.get (ID = любой) .fieldcontent_set.get (независимо) .get_component (). specific_component_field

Чтобы создать новые экземпляры полей, вы можете захотеть добавить вспомогательный метод в модель поля, например:

    def create_content(self, content_object):
        return self.component.get_class().objects.create(
          content_object=content_object, field=self)

Одна вещь, на которую стоит обратить внимание, это то, что все эти вещи обычно приводят к тому, что вы боретесь с фреймворком, места, где Django делал все для вас (формы, администратор и т. Д.), Внезапно становятся чем-то вроде работы, чтобы разобраться , Возможно, стоит взглянуть на то, как некоторые реальные проекты справляются с этим, Django-cms (django-cms.org), вероятно, является хорошим началом.

Просто предупреждение: я не проверял ни один код в этом посте, поскольку я не за компьютером, на котором установлено что-либо полезное, но в целом все должно быть в порядке.

0 голосов
/ 20 марта 2010

Извините, если мне не ясно. Проблема в том, как создавать экземпляры на основе шаблона, а не в том, как создавать шаблоны.

Класс «Мой шаблон» используется для определения того, какие поля содержит данный шаблон и какие клиенты могут его использовать. Мой класс ContentObject предназначен для определения записи контента на основе шаблона.

Еще раз спасибо!

0 голосов
/ 20 марта 2010

Это было бы просто:

my_customer.templates.add(my_template)

, где my_customer и my_template являются экземплярами Customer и Template соответственно.

См. документацию для связанных объектов

...