2

まだ Django を学習しているので、これを行う良い方法があるかどうかはわかりません。

特定の属性 (すべて基本クラスとして Item を使用) を持ついくつかのモデルと、これらのモデル (コード下)。これらのモデルは、フォーム/テンプレート、単純な Web ベースの CRUD で使用されます。

現在、.save_metadata(...) と .load_metadata(...) を明示的に呼び出し、.form_initia(...) を使用して、モデルに明示的に存在しないメタデータをフォームに入力します。

これを自動的に処理する方法を探しています-基本的に、可変数のフィールドを持つモデルを実装します.キーフィールドはモデルのテーブルの列であり、他のフィールドはメタデータテーブルの行であり、インスタンス固有です. objects.get(...) または objects.filter(...) などの後にメソッドをフックする方法はありますか? カスタムマネージャーをいじってシグナルを調べましたが、受け入れられる解決策につながるものは何もないようです.

class Item(models.Model):
  mdata = ['title'] # metadata associated with item

  user = models.ForeignKey(User)
  created = models.DateTimeField(auto_now_add = True)
  status = models.IntegerField(default=0, choices = ([(0,'Staged'), (1,'Published'),(2,'Archived'), ]))

  def set_status(self, s):
    self.status = s
    self.save()

  # stores metadata attributes associated with current item
  def save_metadata(self, lang, form):
    for mt in self.mdata:
      try:
        md = Metadata.objects.get(item=self, lang=lang, t=mt)
      except Metadata.DoesNotExist:
        md = Metadata.objects.create(item=self, lang=lang, t=mt)
      md.v=form.cleaned_data[mt]
      md.save()

  # retrieves metadata attributes associated with current item
  def load_metadata(self, lang):
    for mt in self.mdata:
      self.__dict__[mt] = None
      try:
        self.__dict__[mt] = Metadata.objects.get(item=self, t=mt, lang=lang).v
      except Metadata.DoesNotExist:
        md = Metadata.objects.filter(item=self, t=mt)
        if len(md) > 0:
          self.__dict__[mt] = md[0].v

  # provides metadata attributes associated with current item needed to populate a form
  def form_initial(self, seed=None):
    meta = {}
    for mt in self.mdata:
      meta[mt] = self.__dict__[mt]
      #meta[mt] = 'test'
    if seed:
      meta = dict(meta.items() + seed.items())
    return meta

# used to store various metadata associated with models derived from Item
class Metadata(models.Model):
  item = models.ForeignKey(Item)
  lang = models.CharField(max_length = 8)
  t = models.CharField(max_length = 250)
  v = models.CharField(max_length = 2500)
4

0 に答える 0