嗨,大家好。我正在制作一个Django项目,它是Twitter的简单克隆版本。
因此,我实现了一个Tweet模型和一个Retweet模型,该模型具有原始Tweet和用户的ForeignKey。.
事实是,我希望在主页中同时显示推文和转发,并按创建顺序显示它们。.
我正在使用ModelViewSet
将Django Rest Framework用于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", "
答案 0 :(得分:0)
由于Tweet和Retweet数据驻留在完全不同的模型上,因此要使用当前模型结构进行操作并不容易。要将它们组合到一个视图中,您需要重写ViewSet上的许多内容,并执行诸如在内存中排序这样的操作,这些操作不可伸缩。一种可能的解决方案是使用模型继承,为Tweet和Retweet建立一个基本模型,并在该模型上构建您的serialzier和视图集。可以使用类似以下的模型结构:
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")
使用这些模型后,您可以创建 PostSerializer 和 PostViewSet ,并将它们仅用于列出帖子,您可以继续使用 Tweet 和转推视图和序列化程序,用于创建和更新。