在Django API视图中未获取外键数据

时间:2018-10-14 18:30:38

标签: django django-models django-rest-framework

当前,我有一个网站,希望用户能够查看他们喜欢的文章。我希望将其包含在已设置的用户api视图中。我已经尝试了drf文档中的tracks = serializers.StringRelatedField(many=True),但是没有用。我还尝试了以下方法:

    from rest_framework import serializers

from articles.models import Article, CustomUser,FavoriteArticles


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ('title', 'content')
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = '__all__'

class FavoriteArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = FavoriteArticles
        fields = '__all__'

class UserProfileSerializer(serializers.ModelSerializer):
    fav_title = FavoriteArticleSerializer(read_only=False)
    class Meta:
        model = CustomUser
        fields = 'username, git, email, fav_article, fav_title, homepage'

和我的模型:

from django.db import models
# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db.models.signals import post_save
from django.dispatch import receiver
import uuid



class ProgrammingLanguage(models.Model):
    programming_language = models.CharField(max_length=120, null=False, primary_key=True, default="React")

    def __str__(self):
        return self.programming_language

class Article(models.Model):
    title = models.CharField(max_length=25, primary_key=True)
    content = models.TextField()
    usedfor = models.TextField()
    url=models.CharField(max_length=200, null=True)
    article_programming_language = models.ForeignKey(ProgrammingLanguage, on_delete=models.CASCADE, related_name="article_programming_language", default="react")
    score = models.IntegerField(max_length=5, null=0)

    def __str__(self):
        return self.title

class CustomUser(AbstractUser):
    username = models.CharField(max_length=50, unique=True, primary_key=True)
    git = models.CharField(max_length=200, null=True)
    homepage = models.CharField(max_length=250, null=True)
    user_programming_language = models.ForeignKey(ProgrammingLanguage, on_delete=models.CASCADE, related_name="most_used_programming_language", default="react")
    def __str__(self):
        return str(self.username)


class FavoriteArticles(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    fav_title = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='fav_title')
    reasons_liked = models.CharField(max_length=120, null=True)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name="user", default="tom" )
    def __unicode__(self):
        return '%s: %s' % (self.fav_title, self.reasons_liked)

1 个答案:

答案 0 :(得分:1)

我认为您误解了related_name的含义。它指定如何从模型的反向关系访问模型。因此,建议您从FavoriteArticles模型的字段中删除它,并使用Django已经提供的默认值(在这种情况下为favoritearticles_set):

class FavoriteArticles(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    fav_title = models.ForeignKey(Article, on_delete=models.CASCADE)
    reasons_liked = models.CharField(max_length=120, null=True)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, default="tom")

    def __unicode__(self):
        return '%s: %s' % (self.fav_title, self.reasons_liked)

这样,您可以通过my_user.favoritearticles_set.all()访问用户喜欢的文章。然后,您可以使用source属性将UserSerializer更改为包含liked_articles字段,该字段从favoritearticles_set反向关系填充到用户的FavoriteArticles,使用以下属性:< / p>

class UserSerializer(serializers.ModelSerializer):
    liked_articles = FavoriteArticleSerializer(source='favoritearticles_set', many=True, read_only=True)

    class Meta:
        model = CustomUser
        # explicitly include other fields as required
        fields = ('username', 'git', 'user_programming_language', 'liked_articles')

请注意,我们已经将此字段设置为read_only,因此只有在您执行GET请求时才会填充它。