在聊天应用程序中使用 Rest Framework 身份验证消息过滤 strategy/issue 的 Django 过滤器
Django Filters with Rest Framework Authentication message filtering strategy/issue in a Chat application
我有一个 Django DRF 后端,实现了令牌用户身份验证。该应用程序本身是一个聊天,由 public 大厅和私人线程(特定用户之间的线程)组成。目前我的模型文件包括 Message 模型,它与 Lobby 和 Thread 模型有外键关系,并将这些字段之一保留为 Null,以确定特定消息是否涉及私有线程或 public Lobby。
到目前为止,我一直专注于开发 public 大厅,用户根据他当前所在的大厅查询消息。
在我完成 Lobbies 的开发并启用身份验证后,前端停止按 Lobby 标题过滤消息,只是简单地向我返回与当前经过身份验证的用户相关的所有消息 - 显然忽略了 Lobbies 消息之间的任何区别有关系。检查实际 API 后,我发现当我启用身份验证时,过滤选项从页面上完全消失了。
how can I combat this issue?
编辑:我用一些代码
更新了post
我宁愿保留一个消息模型,也不愿为 Lobby 和 Thread 创建单独的消息模型。
这是我的模型:
class Thread(models.Model):
user1 = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user1")
user2 = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user2")
date = models.DateTimeField(auto_now_add=True, blank=False)
def __repr__(self):
return f"user1: {self.user1} user2: {self.user2}"
class Message(models.Model):
content = models.TextField(max_length=255, default="", blank=False, null=False)
user = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user")
date = models.DateTimeField(auto_now_add=True, blank=False)
lobby = models.ForeignKey(Lobby, on_delete=models.CASCADE, related_name="messages", blank=True, null=True )
thread = models.ForeignKey(Thread, on_delete=models.CASCADE, related_name="messages", blank=True,
null=True )
class Lobby(models.Model):
title = models.TextField(max_length=90, blank=False, null=False)
thumb = models.ImageField(default='lobby.jpg')
这是序列化程序:
class ThreadSerializer(serializers.ModelSerializer):
user1 = serializers.CharField(source="user1.username")
user1thumb = serializers.CharField(source="user1.accountimage.image.url")
user2 = serializers.CharField(source="user2.username")
user2thumb = serializers.CharField(source="user2.accountimage.image.url")
class Meta:
model= Thread
fields = ["user1", "user2", "user1thumb", "user2thumb"]
class MessageSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username')
thumb = serializers.CharField(source='user.accountimage.image.url')
class Meta:
model= Message
fields=['id','content', 'username', 'thumb']
class LobbySerializer(serializers.ModelSerializer):
class Meta:
model=Lobby
fields="__all__"
depth=2
最后是观点:
class ThreadView(viewsets.ModelViewSet):
queryset = Thread.objects.all()
serializer_class = ThreadSerializer
def get_queryset(self):
print(self.request.user)
return Thread.objects.filter(Q(user1= self.request.user) | Q(user2=self.request.user))
class MessageView(viewsets.ModelViewSet):
queryset = Message.objects.all()
serializer_class = MessageSerializer
filter_fields=('lobby__title',)
class LobbyView(viewsets.ModelViewSet):
queryset = Lobby.objects.all()
serializer_class = LobbySerializer
在我的 settings.py 中,我启用了全局身份验证:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
更新:
您的问题与授权无关。您正在添加
"REST_FRAMEWORK"
设置块,但未指定要使用的过滤器后端
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',]
}
并替换
filter_fields = ('lobby__title',)
与:
filterset_fields = ['lobby__title',]
P.S:如果还没有
,则需要pip install django-filter
希望对您有所帮助!
我有一个 Django DRF 后端,实现了令牌用户身份验证。该应用程序本身是一个聊天,由 public 大厅和私人线程(特定用户之间的线程)组成。目前我的模型文件包括 Message 模型,它与 Lobby 和 Thread 模型有外键关系,并将这些字段之一保留为 Null,以确定特定消息是否涉及私有线程或 public Lobby。
到目前为止,我一直专注于开发 public 大厅,用户根据他当前所在的大厅查询消息。
在我完成 Lobbies 的开发并启用身份验证后,前端停止按 Lobby 标题过滤消息,只是简单地向我返回与当前经过身份验证的用户相关的所有消息 - 显然忽略了 Lobbies 消息之间的任何区别有关系。检查实际 API 后,我发现当我启用身份验证时,过滤选项从页面上完全消失了。
how can I combat this issue?
编辑:我用一些代码
更新了post
我宁愿保留一个消息模型,也不愿为 Lobby 和 Thread 创建单独的消息模型。
这是我的模型:
class Thread(models.Model):
user1 = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user1")
user2 = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user2")
date = models.DateTimeField(auto_now_add=True, blank=False)
def __repr__(self):
return f"user1: {self.user1} user2: {self.user2}"
class Message(models.Model):
content = models.TextField(max_length=255, default="", blank=False, null=False)
user = models.ForeignKey(Account, on_delete=models.PROTECT, related_name="user")
date = models.DateTimeField(auto_now_add=True, blank=False)
lobby = models.ForeignKey(Lobby, on_delete=models.CASCADE, related_name="messages", blank=True, null=True )
thread = models.ForeignKey(Thread, on_delete=models.CASCADE, related_name="messages", blank=True,
null=True )
class Lobby(models.Model):
title = models.TextField(max_length=90, blank=False, null=False)
thumb = models.ImageField(default='lobby.jpg')
这是序列化程序:
class ThreadSerializer(serializers.ModelSerializer):
user1 = serializers.CharField(source="user1.username")
user1thumb = serializers.CharField(source="user1.accountimage.image.url")
user2 = serializers.CharField(source="user2.username")
user2thumb = serializers.CharField(source="user2.accountimage.image.url")
class Meta:
model= Thread
fields = ["user1", "user2", "user1thumb", "user2thumb"]
class MessageSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username')
thumb = serializers.CharField(source='user.accountimage.image.url')
class Meta:
model= Message
fields=['id','content', 'username', 'thumb']
class LobbySerializer(serializers.ModelSerializer):
class Meta:
model=Lobby
fields="__all__"
depth=2
最后是观点:
class ThreadView(viewsets.ModelViewSet):
queryset = Thread.objects.all()
serializer_class = ThreadSerializer
def get_queryset(self):
print(self.request.user)
return Thread.objects.filter(Q(user1= self.request.user) | Q(user2=self.request.user))
class MessageView(viewsets.ModelViewSet):
queryset = Message.objects.all()
serializer_class = MessageSerializer
filter_fields=('lobby__title',)
class LobbyView(viewsets.ModelViewSet):
queryset = Lobby.objects.all()
serializer_class = LobbySerializer
在我的 settings.py 中,我启用了全局身份验证:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
更新: 您的问题与授权无关。您正在添加
"REST_FRAMEWORK"
设置块,但未指定要使用的过滤器后端
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':[
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',]
}
并替换
filter_fields = ('lobby__title',)
与:
filterset_fields = ['lobby__title',]
P.S:如果还没有
,则需要pip install django-filter
希望对您有所帮助!