pythondjangoormdjango-ninja

Django Schema Reverse Related Objects


I have the following two Django models:

class Participant(models.Model):
    name = models.TextField()
    sport = models.TextField()

    bookmaker = models.ForeignKey(Bookmaker, on_delete=models.CASCADE)
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ("name", "bookmaker", "sport")

    def __str__(self) -> str:
        return f"{self.name} ({self.sport}) | {self.bookmaker.name}"

class BookmakerParticipant(models.Model):
    sharp_participant = models.OneToOneField(
        Participant, on_delete=models.CASCADE, primary_key=True, 
        related_name="sharp_participant_match"
    )
    soft_participants = models.ManyToManyField(
        Participant, related_name="soft_participant_matches"
    )

    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

In my schema definition I'd like to access all the BookmakerParticipant objects where the Participant is in soft_participants from the Participants perspective. Thus, I created the following schema:

class UnmatchedParticipantSchema(ModelSchema):
    bookmaker: BookmakerSchema
    soft_participant_matches: BookmakerParticipantSchema

    class Meta:
        model = Participant
        fields = [
            "name",
            "sport",
            "bookmaker",
            "soft_participant_matches"
        ]

However, this creates the following error in Django

ninja.errors.ConfigError: DjangoField(s) {'soft_participant_matches'} 
are not in model <class 'core.models.Participant'>.

How do I resolve this?


Solution

  • You can use a resolver:

    class UnmatchedParticipantSchema(ModelSchema):
        bookmaker: BookmakerSchema
        soft_participant_matches: list[BookmakerParticipantSchema]
    
        @staticmethod
        def resolve_soft_participant_matches(obj):
            return list(obj.soft_participant_matches.all())
    
        # ...