Обобщенная модель в Django: Помогите мне с моей логикой, пожалуйста! - PullRequest
2 голосов
/ 21 мая 2011

Мой первый вопрос помог мне очень много, поэтому я решил, что я задам второй.

Мой текущий (практический) проект - создание обобщенной модели. Вот что я написал до сих пор:

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Block(models.Model):
    title = models.CharField(man_length=50)
    #Make sure child classes have content defined!
    #content = models.BooleanField(default=False)
    owner = models.ForeignKey('User')
    access = models.ManytoManyField('User', null=True)
    links = models.ManytoManyField('self', null=True)

    class Meta:
        abstract = True

    def __unicode__(self):
        return self.title


class Text(Block)
    content = models.TextField(max_length=100)

class URL(Block)
    content = models.URLField()

class Email(Block)
    content = models.EmailField()

Обратите внимание, что я на самом деле еще не проверял это - я не думаю, что моя логика в этом пока сработает.

Несколько голов:

1) владелец там указывает на создателя блока. Я думаю, что это должно сработать.

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

3) ссылки должны позволять связывать между блоками - так что я могу получить блок и любые связанные блоки (и так далее, если это необходимо)

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

5) Для классов Email, URL и Text я хотел бы иметь возможность написать (обобщенное) представление, которое из одного ввода URL возвращает соответствующий блок любого из трех типов. Я думаю, что для этого может потребоваться автоинкрементное поле, которое гарантирует уникальное значение между тремя моделями. Честно говоря, я вообще не знаю, как это сделать.

6) Конечно, в идеале это должно быть легко расширяемым, если это вообще возможно.

Я, конечно, очень не уверен, что это лучший способ добиться того, что я пытаюсь сделать. Любые предложения, помощь, советы, хитрости или плохие шутки принимаются!

Большое спасибо за помощь!

РЕДАКТИРОВАТЬ: в отношении числа 5 у меня есть грубое представление (с синтаксической ошибкой), которое, я думаю, может помочь:

def getblock(request, block, no):
    data = get_object_or_404(%s,%s) % (block,no)
    return render_to_response('single.html',{'data':data})

Мысли

1 Ответ

2 голосов
/ 26 мая 2011

Ваш код мне кажется правильным.Я также работал над общим классом для моего проекта, и он был похож на этот.Одно замечание: когда вы получаете блок, вы должны выполнить некоторую проверку типов для извлечения данных класса, поэтому я рекомендую вам добавить поле для хранения его типа.Например:

class Block(models.Model):
  title = models.CharField(max_length=50)
  type = models.IntegerField()# 1 for text, 2 for email and 3 for url
  #Make sure child classes have content defined!
  #content = models.BooleanField(default=False)
  owner = models.ForeignKey('User')
  access = models.ManytoManyField('User', null=True)
  links = models.ManytoManyField('self', null=True)

Тогда, на ваш взгляд:

def getblock(request, block, no):
  if block.type == 1:
    data = get_object_or_404(Block,id=no).text
  elif block.type == 2:
    data = get_object_or_404(Block,id=no).email
  elif block.type == 3:
    data = get_object_or_404(Block,id=no).url
  return render_to_response('single.html',{'data':data})

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

...