2

異なるアプリ ディレクトリに 2 つの models.py ファイルがあります: users.models.py と friends.models.py。

問題が 1 つあります。UserProfile モデルからユーザーを削除した場合、そのユーザーの友情ネットワークもすべて削除する必要があります。とても自然です。

しかし、Friendship を users.model.py にインポートすると、次のエラーが表示されます: Cannot import name Friendship

これら 2 つのファイルの相互インポートが原因でエラーが発生したことは理解しており、シグナルを使用してこの問題を簡単に解決できることはわかっていますが、適切な方法でそれを行う方法がわかりません。

この特定のケースで誰か助けてもらえますか?

users.models.py で:

from friends.models import Friendship

class UserProfile(models.Model):
    username = models.Charfield(max_length=50)
    ...

    def delete(self, *args, **kwargs):
        Friendship.objects.remove_all(self)
        self.delete(*args, **kwargs)

friends.models.py で:

from users.models import UserProfile

class FriendshipManager(models.Manager):
    def remove_all(self, user):
        usr = Friendship.objects.get(user=user).friends
        frs = [i.user for i in usr.all()]
        for fr in frs:
            usr.remove(fr)

class Friendship(models.Model):
    user = models.Foreignkey(UserProfile)
    friends = models.ManyToManyField('self')

    objects = FriendshipManager()

前もって感謝します!!!

4

2 に答える 2

1

これは私が通常行っていることです。これを簡単にリファクタリングして、モデルで実装できます

from django.db import models
from django.db.models.signals import post_save, post_delete
from django.contrib.auth.models import User

# App specific


class UserProfile(models.Model):
    """
    Adds a basic UserProfile for each User on the fly.
    """
    user = models.OneToOneField(User)
    avatar = models.ImageField(upload_to='example/somewhere', blank=True)

    def __str__(self):
          return "%s's profile" % self.user

    def get_avatar(self):
        return '/'+self.avatar

    def clean_avatar(self):
        # TODO: imagekit
        pass

    class Meta:
        app_label = 'users'

    def save(self, *args, **kwargs):
        if self.id:
            this = UserProfile.objects.get(id=self.id)
            if this.avatar:
                if this.avatar != self.avatar:
                    this.avatar.delete(save=False)
        super(UserProfile, self).save()

def create_user_profile(sender, instance, created, **kwargs):
    if created:
       profile, created = UserProfile.objects.get_or_create(user=instance)

post_save.connect(create_user_profile, sender=User)


def UserProfileDelete(instance, **kwargs):
    """
    Documentatie
    """
    instance.avatar.delete(save=False)

post_delete.connect(UserProfileDelete, sender=UserProfile)
于 2011-10-28T14:43:27.857 に答える
1

シグナルは必要ありません。魔法の *_set プロパティを使用するだけです。実行時に定義されるため、循環インポートについて心配する必要はありません。

友達/models.py

from users.models import UserProfile

class Friendship(models.Model):
    user = models.Foreignkey(UserProfile)
    friends = models.ManyToManyField('self')

ユーザー/models.py

class UserProfile(models.Model):
    username = models.Charfield(max_length=50)
    ...

    def delete(self, *args, **kwargs):
        for f in self.friendship_set.all():
            f.delete()
        super(self.__class__, self).delete(*args, **kwargs)
于 2011-10-28T14:44:57.980 に答える