Serializing Foreign Key Field

2019-08-16 03:14发布

问题:

I have the following models:

class Question(models.Model):
    test = models.ForeignKey(Test, on_delete=models.CASCADE)
    text = models.CharField(max_length=255,default='',blank=False)
    number = models.IntegerField()

    def __str__(self):
        return self.text

class Test(models.Model):
    PRIVACY_TYPES = (
        ('PR', 'Private'),
        ('PU', 'Public'),
    )
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    name = models.CharField(max_length=255,default='',blank=False)
    datecreated = models.DateTimeField(auto_now=True)
    privacy = models.CharField(choices=PRIVACY_TYPES, default='PR',max_length=15)
    testtime = models.IntegerField(default=30)


class User(AbstractBaseUser, models.Model):
    username = models.CharField(max_length=20,default='',blank=True)
    password = models.CharField(max_length=80,default='',blank=True)
    email = models.CharField(max_length=255,default='',blank=True)

I am trying to serialize the test object to also include the username and id from the User model. Here is the serializer I am trying:

class TestSerializer(serializers.ModelSerializer):
    question_set = QuestionSerializer(many=True)
    user = UserSerializer(source='user')

    class Meta:
        model = Test
        fields = ('id', 'name', 'privacy', 'testtime', 'user', 'question_set')
        related_object = 'question'

The user serializer looks like:

class UserSerializer(serializers.Serializer):
    class Meta:
        model = User
        fields = ('id', 'username')

The question set serializes fine this way, but with the relationship the other way round, if that is the right way to describe it, for user then I get an empty object with this code. I have tried user_username and user.username in the fields, but that doesn't work.

I have searched online and looked at the Django-Rest-Framework documents, but can only find examples where the relationship is as the question to test.

回答1:

I hope, I understand your question correctly.

Your models.py

class Question(models.Model):
        test = models.ForeignKey(Test, on_delete=models.CASCADE)
        text = models.CharField(max_length=255,default='',blank=False)
        number = models.IntegerField()

        def __str__(self):
            return self.text



class Test(models.Model):
        PRIVACY_TYPES = (
            ('PR', 'Private'),
            ('PU', 'Public'),
        )
        user = models.ForeignKey(User, on_delete=models.PROTECT)
        name = models.CharField(max_length=255,default='',blank=False)
        datecreated = models.DateTimeField(auto_now=True)
        privacy = models.CharField(choices=PRIVACY_TYPES, default='PR',max_length=15)
        testtime = models.IntegerField(default=30)

My question is updated to show you what ForeignKey means. ForeignKey means ManyToOne. You have ForeignKey field in Question Model with reference to Test Model. Idea is, that you have Many Question and One Test (ManyToOne), and vice-versa One Test and Many Question.

This is solution below.

class TestSerializer(serializers.ModelSerializer):
    question_set = QuestionSerializer(many=True)
    user = serializers.ReadOnlyField(source='user.username')

    class Meta:
        model = Test
        fields = ('id', 'name', 'privacy', 'testtime', 'user', 'question_set')
        related_object = 'question'

And now use it,,,

test_obj = Test.objects.get(pk=1)
test_serializer = TestSerializer(instance=test_obj)
print(test_serializer.data)