【问题标题】:Django list data from dfiferent models in List View with correct ordering列表视图中来自不同模型的 Django 列表数据具有正确的顺序
【发布时间】:2019-08-11 01:06:18
【问题描述】:

嘿,伙计们.. 我正在制作一个 Django 项目,它是 Twitter 的简单克隆.. 从 Justin Mitchell 的 Udemy 课程中得到这个想法..
所以我实现了一个 Tweet 模型和一个 Retweet 模型,它具有原始 Tweet 和用户的 ForeignKey..
问题是,在主页中,我希望推文和转推都按照它们的创建顺序显示..
我正在使用 Django Rest Framework 使用 ModelViewSet
实现 Tweet 的 CRUD 功能 关于我如何使用 Rest Framework 实现这一点的任何想法,或者如果这不可能,请给我一些其他想法..
提前谢谢你..

models.py

class Tweet(models.Model):
   content = models.CharField(max_length=140)
   user = models.ForeignKey(User, on_delete=models.CASCADE)
   created_on = models.DateTimeField(auto_now_add=True)
   updated_on = models.DateTimeField(auto_now=True)

   class Meta:
       ordering = "-created_on", "content", "user",

   def __str__(self):
       return self.content

   def get_absolute_url(self):
       return reverse("tweet_api:tweet-detail", args=[self.id])


class Retweet(models.Model):
    tweet = models.ForeignKey(Tweet, on_delete=models.CASCADE, related_name="retweet")
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = "-created_on", "user",

    def __str__(self):
        return self.tweet.content

serializers.py

class TweetSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    created_on = serializers.SerializerMethodField()
    date_display = serializers.SerializerMethodField()

    class Meta:
        model = models.Tweet
        fields = "id", "content", "created_on", "date_display", "user",

    def get_created_on(self, obj):
        return obj.created_on.strftime("%I:%M %p - %d %b %Y")

    def get_date_display(self, obj):
        obj_date = obj.created_on
        days = (timezone.datetime.now() - obj_date).days
        if days > 0:
            return obj_date.strftime("%d %b")
        else:
            return naturaltime(obj_date)

class RetweetSerializer(serializers.ModelSerializer):
    tweet = TweetSerializer()
    user = UserSerializer(read_only=True)
    date_display = serializers.SerializerMethodField()

    class Meta:
        model = models.Retweet
        fields = "id", "tweet", "user", "created_on", "date_display",

    def get_date_display(self, obj):
        obj_date = obj.created_on
        days = (timezone.datetime.now() - obj_date).days
        if days > 0:
            return obj_date.strftime("%d %b")
        else:
            return naturaltime(obj_date)

views.py

class TweetViewSet(ModelViewSet):
    serializer_class = serializers.TweetSerializer
    queryset = models.Tweet.objects.all()
    pagination_class = DefaultPagination
    filter_backends = filters.SearchFilter,
    search_fields = "content", "user__username", "user__first_name", "user__last_name",

    def perform_create(self, serialiazer):
        return serialiazer.save(user=self.request.user)


class RetweetViewSet(ModelViewSet):
    serializer_class = serializers.RetweetSerializer
    queryset = models.Retweet.objects.all()
    pagination_class = DefaultPagination
    filter_backends = filters.SearchFilter,
    search_fields = "tweet__content", "user__username", "user__first_name", "

【问题讨论】:

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


    【解决方案1】:

    由于 Tweet 和 Retweet 数据驻留在完全不同的模型上,您想要做的事情对于您当前的模型结构并不简单。要将它们组合在一个视图中,您需要覆盖 ViewSet 上的许多内容,并执行诸如在内存中排序之类的操作,这将是不可扩展的。一种可能的解决方案是使用模型继承,为 Tweet 和 Retweet 提供一个基本模型,并在该模型上构建您的序列化程序和视图集。可以使用如下模型结构:

    class Post(models.Model):
        """
        Base model for user posts
        """
        user = models.ForeignKey(User, on_delete=models.CASCADE)
        created_on = models.DateTimeField(auto_now_add=True)
    
    class Tweet(Post):
        content = models.CharField(max_length=140)
        updated_on = models.DateTimeField(auto_now=True)
    
    class Retweet(Post):
        tweet = models.ForeignKey(Tweet, on_delete=models.CASCADE, related_name="retweet")
    

    有了这些模型,您可以创建 PostSerializerPostViewSet,并将它们仅用于列出帖子,您可以继续使用 Tweet转推 用于创建和更新的视图和序列化程序。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2021-05-02
    • 2020-09-06
    • 2022-01-19
    相关资源
    最近更新 更多