2017-02-12 4 views
0

どのアプリケーションでも使用できる汎用モデルを定義したいと思います。私の一般的なモデルの定義は次のとおりです。 - (一般的なモデルを利用し、上記で定義された)次のようにdjangoでジェネリックモデルを定義する際の循環依存性を解決する方法

User = settings.AUTH_USER_MODEL 
# This mixin is used to track the user, who has created this object. 
class OwnedModel(models.Model): 
     owner   = ForeignKey(to=User, null=True, editable=False) 

     class Meta: 
      abstract = True 

# AreaOrVillage extending this model, will also get owner field, which 
# refer to User. 
class AreaOrVillage(OwnedModel): 

    area_village_name = LocationIdentifierField(name="areaOrVillageName", verbose_name="Area/Village:", blank=False, null=False) 
    area_village_code = LocationCodeField(name="areaOrVillageCode", verbose_name="Area/Village Code", null=True, blank=True) 
    zipcode    = ZipCodeField(verbose_name="ZipCode", null=False, blank=False) 
    # It's another model, referred by this model 
    tehsil    = models.ForeignKey(to=Tehsil, related_name="areas_or_villages") 

    class Meta: 
     verbose_name_plural = "Areas/Villages" 
     unique_together  = ("tehsil", "areaOrVillageName") 
     ordering   = ("tehsil", "areaOrVillageName") 
     app_label   = 'location_app' 

    def __str__(self): 
     text    = self.to_str() 
     return "{}{}{}".format(text, ", " if text and self.tehsil else "", 
           self.tehsil.__str__() if self.tehsil else "") 

    def to_str(self): 
     return "%s" %(self.areaOrVillageName or self.areaOrVillageCode) 

さて、私のDjangoプロジェクトでは、私がオーバーライドされているデフォルトのユーザーモデルは: -

class PSS_User_Type(ModelBase): 

    def __new__(cls, name, bases, dictattrs): 
     user_type = super(PSS_User_Type, cls).__new__(cls, name, bases, dictattrs) 

     OVER_RIDDEN_ATTR = "is_staff" 
     NEW_ATTR   = "is_devteam_member" 

     if hasattr(user_type, OVER_RIDDEN_ATTR): 
      setattr(user_type, NEW_ATTR, 
        getattr(user_type, OVER_RIDDEN_ATTR)) 
      delattr(user_type, OVER_RIDDEN_ATTR) 

      setattr(user_type, "__getattr__", PSS_User_Type.__getattr__) 

     def __getattr__(self, attrname): 
      effective_attr = NEW_ATTR if attrname == OVER_RIDDEN_ATTR else attrname 
      return super(cls, self).__getattr__(attrname) 

     return user_type 

class PSS_User(LoggableModel, OwnedModel, ResolvableModelMixin, AbstractUser): 

    __metaclass__ = PSS_User_Type 

    REQUIRED_FIELDS = ['password', 'first_name', 'last_name', 
         'village', 'gotra'] 

    # TODO :- Add phone/mobile no details 

    dob = DateField(null=True, blank=True) 
    age = SmallIntegerField(null=True, blank=True, validators=[AgeValidator()]) 
    is_alive = BooleanField(null=False, blank=False, default=True) 
    gender = GenderField(null=False, blank=False) 
    user_village = ForeignKey(to=AreaOrVillage, null=False, related_name="gram_vasi") 

さて、一般的なモデルは、ユーザーに応じていることから、その作成者を追跡するために、循環依存の問題を導入しています、ユーザー定義はまた、DBに対して、マイグレーションを実行している先の問題

django.db.utils.ProgrammingError: relation "users_pss_user" does not exist 
に与えている、一般的なモデルを使用しています

この問題を解決する方法はありますか?

ありがとうございます。

答えて

0

ForeignKeycan also be a stringtoフィールド:たとえば

If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:

(強調追加)

は、あなたのコードからは、次の操作を行うことができます:

user_village = ForeignKey(to='AreaOrVillage', null=False, related_name="gram_vasi") 

その構文を使用します。すべてのForeignKeyフィールドに入力してください。循環参照は避けてください。

+0

エラー:users.PSS_User.user_village :(fields.E300)フィールドは、インストールされていないモデル、または抽象モデルのモデル 'AreaOrVillage'とのリレーションを定義します。 –

+0

あなたは 'ForeignKey'フィールドの** all **にこの構文を使用しましたか? – 2ps

+0

はい、私はこの構文を外部キーに使用しました。 Btw、app nameも含める必要があるので、私はForeignKey()の引数に 'appname.modelname'を設定しました。 –

関連する問題