0

単純に制限された ForeignKey である一連のカスタム ModelField を作成しました。その下に CompanyField があります。インスタンス化する際に、タイプ (クライアント、ベンダーなど) を指定できます。タイプを指定すると、フィールドは適切なタイプの値のみが許可されるようになります。

カスタム フィールドを定義する crm アプリは、問題なくコンパイルおよび実行されます。最終的に、「from crm import fields」を使用して、フィールドへの参照を別のアプリ (インシデント) に追加しました。今、私は次のようなたくさんのエラーを見ています:

Incidents.incident: 'group' は、インストールされていないか抽象的であるモデル会社と関係があります。

ここにすべての悲惨な詳細があります。他に役立つ情報があれば教えてください。

## crm/fields.py

import models as crmmods

class CompanyField(models.ForeignKey):
    def __init__(self, *args, **kwargs):
        # This is a hack to get South working. In either case, we just need to
        # make sure the FK refers to Company.
        try:
            # kwargs['to'] == crmmods.company doesn't work for some reason I
            # still haven't figured out
            if str(kwargs['to']) != str(crmmods.Company):
                raise AttributeError("Only crm.models.Company is accepted " + \
                    "for keyword argument 'to'")
        except:
            kwargs['to'] = 'Company'

        # See if a CompanyType was provided and, if so, store it as self.type
        if len(args) > 0:
            company_type = args[0]
            # Type is expected to be a string or CompanyType
            if isinstance(company_type, str):
                company_type = company_type.upper()
                if hasattr(crmmods.CompanyType, company_type):
                    company_type = getattr(crmmods.CompanyType, company_type)
                else:
                    raise AttributeError(
                        "%s is not a valid CompanyType." % company_type)
            elif not isinstance(company_type, crmmods.CompanyType):
                raise AttributeError(
                    "Expected str or CompanyType for first argument.")

            self.type = company_type
        else:
            self.type = None

        super(CompanyField, self).__init__(**kwargs)

    def formfield(self, **kwargs):
        # Restrict the formfield so it only displays Companies with the correct
        # type.
        if self.type:
            kwargs['queryset'] = \
                crmmods.Company.objects.filter(companytype__role=self.type)
        return super(CompanyField, self).formfield(**kwargs)

    def validate(self, value, model_instance):
        super(CompanyField, self).validate(value, model_instance)

        # No type set, nothing to check.
        if not value or not self.type:
            return

        # Ensure that value is correct type.
        if not \
        value.companytype_set.filter(role=self.type).exists():
            raise ValidationError("Company does not have the " + \
                "required roles.")

## crm/models.py

import fields

class CompanyType(models.Model):
    name = models.CharField(max_length=25)

class Company(models.Model):
    type = models.ForeignKey(CompanyType)

class Person(models.Model):
    name = models.CharField(max_length=50)
    company = fields.CompanyField("Client")

## incidents/models.py

from crm import fields as crmfields

class Incident(models.Model):
    company = crmfields.CompanyField("Client")
4

2 に答える 2

1

循環パッケージ依存関係があります。fields輸入品 輸入models品 輸入品 輸入品 輸入品 輸入品 輸入品 輸入品 輸入品 輸入品fields輸入品models輸入fields品 . .

循環パッケージの依存関係は A BAD IDEA(tm) です。場合によってはうまくいくかもしれませんが、メタクラスが関係する複雑な理由で、あなたの場合はうまくいきません。

編集

その理由は、Django ORM モジュールがメタクラスを使用して、そのクラス変数 (モデルのフィールド) をオブジェクトのプロパティ記述子に変換するためです。これは、メタクラスによってクラス定義時に行われます。モジュールのロード時にクラスが定義されます。このため、その属性もクラスのロード時に定義する必要があります。これは、クラスが実行された瞬間に名前への参照が解決されるメソッドのコードとは異なります。

ここで、fieldクラス定義内のオブジェクトを参照したり、参照したりするためmodels、これは機能しません。

3つすべてを同じパッケージに入れると、問題は解決します.

于 2012-09-20T20:52:55.163 に答える
0

苦労の末、変更するだけで修正されました

kwargs['to'] = 'Company'

kwargs['to'] = 'crm.Company'

「to」引数がcrmアプリの外部で評価された場合、インシデントアプリのコンテキストで評価されていたようです。つまり、エラー メッセージが示すように存在しない「incidents.Company」を探していました。

于 2012-09-24T22:36:59.950 に答える