Pertanyaan Django Reverse Accessor Clashes


Jadi di sini saya mengalami banyak masalah dengan bentrokan pengakses terbalik. Saya pikir saya cukup pintar dan KERING dengan struktur model saya untuk dapat menggunakan user.profile untuk semua jenis profil, atau menggunakan provider.profile untuk salah satu penyedia ... tapi saya mendapatkan kesalahan bentrok di semua tempat .

Pikiran yang melihat kode saya dan melihat apakah ada cara bagi saya untuk membohongi ini sehingga saya masih bisa hanya user.profile tanpa perlu mengetahui yang jenis profil (dan penyedia juga. Profil tanpa perlu tahu jenis pemberi)? Atau hanya mengatakan kepada saya bahwa apa yang saya coba lakukan tidak mungkin dan ada solusi yang lebih baik?

class BaseProfileModel(models.Model):
    '''
    An abstract model class containing fields and/or methods relevant to all users.
    '''
    user = models.OneToOneField(User, related_name="profile", primary_key=True)
    phone = PhoneNumberField(verbose_name=_("Phone Number"))
    pic = models.ImageField(upload_to=get_upload_file_name,
                            width_field="width_field",
                            height_field="height_field",
                            null=True,
                            blank=True,
                            verbose_name=_("Profile Picture")
                           )
    height_field = models.PositiveIntegerField(null=True, default=0)
    width_field = models.PositiveIntegerField(null=True, default=0)
    thumbnail = ImageSpecField(source='pic',
                                   processors=[ResizeToFill(180,180)],
                                   format='JPEG',
                                   options={'quality': 100})
    bio = models.TextField(
        verbose_name=_("About"),
        default="",
        blank=True,
        max_length=800
    )

    class Meta:
        abstract = True

    def __str__(self):
        if self.user.email:
            return self.user.email
        else:
            return self.user.username

    @property
    def is_provider(self):
        return hasattr(self, 'provider')

    def get_absolute_url(self):
        return reverse_lazy(self.profile_url_name, kwargs={'pk': self.pk})

    # Methods

class BaseHumanProfileModel(BaseProfileModel):
    '''
    Abstract base class containing fields relevant to human users
    '''
    birth_date = models.DateField(verbose_name=_("Date of Birth"))
    GENDER_CHOICES = (
        ('M', _('Male')),
        ('F', _('Female')),
        ('N', _('Not Specified')),
    )
    gender = models.CharField(
        max_length=1, choices=GENDER_CHOICES, default='N', verbose_name=_('Gender'))

    class Meta:
        abstract = True

class CustomerProfile(BaseHumanProfileModel):
    '''
    Concrete Human subclass for the consumers
    '''
    home_location = models.OneToOneField(
        Location,
        related_name='customer',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
        )
    profile_url_name = 'profiles:customer_profile'

    # Methods

class Provider(models.Model):
    '''
    Class containing information needed for providers
    Other models (provider profiles, reviews, events, etc.) will use this class
    as ForeignKey to interface with functionalities related to creating and managing
    sessions/listings.
    '''
    stripe_access_token = models.TextField(blank=True, default='')

    # Methods....


class IndividualProviderProfile(BaseHumanProfileModel):
    '''
    Concrete subclass for representing the profile of an individual provider.
    '''
    provider = models.OneToOneField(Provider, related_name='profile')
    locations = models.ManyToManyField(Location, null=True, blank=True, related_name='individual_providers')
    specialties = models.CharField(
        verbose_name=_("Specialties"),
        max_length=200,
        blank=True,
    )
    certifications = models.CharField(
        verbose_name=_("Certifications"),
        max_length=200,
        blank=True,
    )
    profile_url_name = 'profiles:individual_provider_profile'

    # methods


class OrganizationProviderProfile(BaseProfileModel):
    '''
    Profile representing a provider that is an organization.
    Contains key to provider class for interfacing with session scheduling
    Also contains set of individual providers that work for the organization.
    '''
    provider = models.OneToOneField(Provider, related_name='profile')
    website = models.URLField(blank=True)
    location = models.ForeignKey(Location, related_name='organization')
    employees = models.ManyToManyField(IndividualProviderProfile, null=True, blank=True, related_name='organization')

    @property
    def locations(self):
        return Locations.objects.filter(pk=self.location.pk)

    profile_url_name = 'profiles:organization_provider_profile'

    #methods

Sekarang ketika saya mencoba untuk menyelaraskan db, saya mendapatkan rangkaian peringatan yang agak panjang dan intens ini:

CommandError: System check identified some issues:

ERRORS:
profiles.CustomerProfile.user: (fields.E304) Reverse accessor for 'CustomerProfile.user' clashes with reverse accessor for 'OrganizationProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'CustomerProfile.user' or 'OrganizationProfile.user'.
profiles.CustomerProfile.user: (fields.E304) Reverse accessor for 'CustomerProfile.user' clashes with reverse accessor for 'IndividualProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'CustomerProfile.user' or 'IndividualProviderProfile.user'.
profiles.CustomerProfile.user: (fields.E305) Reverse query name for 'CustomerProfile.user' clashes with reverse query name for 'OrganizationProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'CustomerProfile.user' or 'OrganizationProviderProfile.user'.
profiles.CustomerProfile.user: (fields.E305) Reverse query name for 'CustomerProfile.user' clashes with reverse query name for 'IndividualProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'CustomerProfile.user' or 'IndividualProviderProfile.user'.
profiles.OrganizationProfile.provider: (fields.E304) Reverse accessor for 'OrganizationProviderProfile.provider' clashes with reverse accessor for 'IndividualProviderProfile.provider'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.provider' or 'IndividualProviderProfile.provider'.
profiles.OrganizationProviderProfile.provider: (fields.E305) Reverse query name for 'OrganizationProviderProfile.provider' clashes with reverse query name for 'IndividualProviderProfile.provider'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.provider' or 'IndividualProviderProfile.provider'.
profiles.OrganizationProviderProfile.user: (fields.E304) Reverse accessor for 'OrganizationProviderProfile.user' clashes with reverse accessor for 'CustomerProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.user' or 'CustomerProfile.user'.
profiles.OrganizationProviderProfile.user: (fields.E304) Reverse accessor for 'OrganizationProviderProfile.user' clashes with reverse accessor for 'IndividualProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.user' or 'IndividualProvider.user'.
profiles.OrganizationProviderProfile.user: (fields.E305) Reverse query name for 'OrganizationProviderProfile.user' clashes with reverse query name for 'CustomerProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.user' or 'CustomerProfile.user'.
profiles.OrganizationProviderProfile.user: (fields.E305) Reverse query name for 'OrganizationProviderProfile.user' clashes with reverse query name for 'IndividualProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'OrganizationProviderProfile.user' or 'IndividualProvider.user'.
profiles.IndividualProviderProfile.provider: (fields.E304) Reverse accessor for 'IndividualProviderProfile.provider' clashes with reverse accessor for 'OrganizationProviderProfile.provider'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.provider' or 'OrganizationProviderProfile.provider'.
profiles.IndividualProviderProfile.provider: (fields.E305) Reverse query name for 'IndividualProviderProfile.provider' clashes with reverse query name for 'OrganizationProviderProfile.provider'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.provider' or 'OrganizationProviderProfile.provider'.
profiles.IndividualProviderProfile.user: (fields.E304) Reverse accessor for 'IndividualProviderProfile.user' clashes with reverse accessor for 'CustomerProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.user' or 'CustomerProfile.user'.
profiles.IndividualProviderProfile.user: (fields.E304) Reverse accessor for 'IndividualProviderProfile.user' clashes with reverse accessor for 'OrganizationProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.user' or 'OrganizationProviderProfile.user'.
profiles.IndividualProviderProfile.user: (fields.E305) Reverse query name for 'IndividualProviderProfile.user' clashes with reverse query name for 'CustomerProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.user' or 'CustomerProfile.user'.
profiles.IndividualProviderProfile.user: (fields.E305) Reverse query name for 'IndividualProviderProfile.user' clashes with reverse query name for 'OrganizationProviderProfile.user'.
    HINT: Add or change a related_name argument to the definition for 'IndividualProviderProfile.user' or 'OrganizationProviderProfile.user'.

32
2017-11-16 08:51


asal


Jawaban:


related_nameharus unik. Anda memberi nama yang sama untuk semua related_name's.

Cobalah untuk mengganti nama mereka seperti ini:

user = models.OneToOneField(User, related_name="custom_user_profile", primary_key=True)
#..
provider = models.OneToOneField(Provider, related_name='user_ind_provider_profile')
#..
provider = models.OneToOneField(Provider, related_name='user_org_provider_profile')

42
2017-11-16 08:55