根据用户显示不同的页面 - django

Show different pages based on user - django

我正在构建类似 IMDB 的网络应用程序。每个(登录的)用户查看完全相同的主页,但他们可以 flag/unflag 将他们想要的每部电影保存在“已看列表”中。我已经这样做了,但我注意到每个登录的用户都可以查看其他用户标记的电影。当然这是个问题,所以我想为每个用户建立一个页面,这样每个人都会有不同的“看过的电影”页面,这些页面是基于标记为看过的电影。 这背后的主要思想是,每当用户将电影添加到数据库时,他都可以在电影模型中用简单的 models.BooleanField 标记它。然后我有另一个模型“Seen”,其中标记了所有电影。

models.py

class Films(models.Model):
    ...
    seen = models.BooleanField(default=False)
class Seen(models.Model):
    ...

views.py

    films = Films.objects.all()
    for film in films:
    flag = 0
    seen_films = Seen.objects.all()
    for _ in seen_films:
        if film.name == _.name:
            flag = 1
            break
    if not flag and film.seen:
        act_seen = Seen(image=film.image, name=film.name, description=film.description)
        act_seen.save()

我需要为用户添加,我使用django提供的默认class:

from django.contrib.auth.models import User

我知道错误是每个人都可以 flag/unflag 一部电影,所以每个人都可以看到其他用户的电影,但我不知道如何解决这个问题。此外,我认为 views.py 中的代码非常原始,但它比最终产品更像是一个测试。谢谢!

您可以 extend the default User class(查看文档,有几种方法可以做到这一点,我使用的可能不是最适合您的方法)并使用 many-to-many 保存所有用户看过的电影:

# models.py
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    films_seen = models.ManyToManyField(Films, related_name='seen_by')

然后你可以使用 ListAPIView 并覆盖 get_queryset() 方法:

# views.py
from rest_framework.generics import ListAPIView

class FilmsSeenList(ListAPIView):
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        return self.request.user.profile.films_seen.all()

请注意,您必须确保每个用户都有一个关联的配置文件(例如带有信号 docs here),否则 get_queryset() 会引发 Profile.DoesNotExist:

# handlers.py
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver

from accounts.models import Profile  # Define where your Profile model is here

User = get_user_model()


@receiver(post_save, sender=User, dispatch_uid="create_profile")
def post_save_user(sender, instance, created, **kwargs):
    # Making sure that a profile is assigned for new users
    if created:
        Profile.objects.create(user=instance)

您还可以实现一个返回所有电影的视图和一个标志以了解用户是否看过电影:

# views.py
from rest_framework.generics import ListAPIView

class AllFilmsList(ListAPIView):
    permission_classes = (IsAuthenticated,)
    serializer_class = FilmsSeenFlagSerializer

    def get_queryset(self):
        return Films.objects.all()


# serializers.py
class FilmsSeenFlagSerializer(serializers.ModelSerializer):
    seen = serializers.SerializerMethodField()

    def get_seen(self, instance):
        return instance.seen_by.filter(pk=self.context['request'].user.pk).exists()

    class Meta:
        model = Films
        fields = [..., 'seen']