基于外键用户字段的 Django Rest Framework ViewSet 过滤问题
Django Rest Framework ViewSet filtering issue based on foreignkey User field
我有一个正在处理的 Django 项目。这个项目有两个模型。有一个 user
和 account
模型。我正在整合 django rest 框架视图集。我将在下面包括它们。我现在正在项目中集成 Django Rest Framework。我想弄清楚如何做两件事。
2 个模型:
默认 django 用户
账户模型:
class Account(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
_id = models.CharField(max_length=45)
name = models.CharField(max_length=140)
balance = models.DecimalField(max_digits=100, decimal_places=2)
currency = models.CharField(max_length=12)
bank_name = models.CharField(max_length=120)
routing = models.CharField(max_length=8)
_class = models.CharField(max_length=22)
type = models.CharField(max_length=22)
active = models.BooleanField(default=True)
main = models.BooleanField(default=False)
synapse = models.BooleanField(default=False)
create_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username + ' - ' + self.name + ': ' + str(self.balance)
1 => 我希望能够输入端点 /api/users/accounts/omarjandlai
并使用 omarjandali 用户外键
获取单个或多个帐户
2 => 我希望能够输入以下内容
api/users/accounts/
和 return 数据库中的所有帐户
我尝试了 4 - 5 种不同的方法来让它工作,但我无法让它工作。
这是我的序列化程序和视图
序列化程序:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('user', '_id', 'name', 'balance', 'currency', 'bank_name',
'routing', '_class', 'type', 'active', 'main', 'synapse')
观看次数:
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('user',)
发生的事情是,当我执行
api/users/account
我看到了所有的账户
api/users/account/omarjandali
我得到 detail not found
网址:
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = router.urls
我可以看到您正在使用 DefaultRouter 的默认功能。这样您只能使用他们的主键访问记录详细信息。由于您没有明确指定任何字段作为主键 (primary=True
),Django 设置字段 id,即 PositiveIntegerField
作为模型的主键。因此,如果您想访问记录的详细信息,则必须使用 api/users/account/112/
.
您可以使用过滤器按名称访问记录:api/users/account/?search='omarjandali'
,但您需要添加 SearchFilter
。
from rest_framework.filters import SearchFilter
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend, SearchFilter)
filter_fields = ('user',)
search_fields = ('name',)
如果你想坚持 url 模式 api/users/account/omarjandali/
,你必须将它添加到 urls.py 并使用另一个视图集为了让原始路由器根据 DefaultRouter 定义运行:
urls.py:
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = [
path('', include(router.urls)),
path('api/users/account/<str:username>/', views.GetRecordsByNameViewSet.as_view({'get': 'list'}),
]
views.py
from rest_framework.response import Response
class GetRecordsByNameViewSet(viewsets.ViewSet):
def list(self, request, username):
accounts = Account.objects.filter(user__username=username)
accounts_to_return = AccountSerializer(accounts, many=True).data
return Response(accounts_to_return)
您可以尝试覆盖
get_queryset (method)
这样就无需在 URL 中提供 username/email。你会做 localhost8000/accounts,它只会显示相应用户的帐户。
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('user',)
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(user=self.request.user)
return queryset
注意:如果在项目中设置了身份验证,这将起作用。在令牌认证的情况下,您需要在授权中提供令牌 header.
我有一个正在处理的 Django 项目。这个项目有两个模型。有一个 user
和 account
模型。我正在整合 django rest 框架视图集。我将在下面包括它们。我现在正在项目中集成 Django Rest Framework。我想弄清楚如何做两件事。
2 个模型:
默认 django 用户
账户模型:
class Account(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
_id = models.CharField(max_length=45)
name = models.CharField(max_length=140)
balance = models.DecimalField(max_digits=100, decimal_places=2)
currency = models.CharField(max_length=12)
bank_name = models.CharField(max_length=120)
routing = models.CharField(max_length=8)
_class = models.CharField(max_length=22)
type = models.CharField(max_length=22)
active = models.BooleanField(default=True)
main = models.BooleanField(default=False)
synapse = models.BooleanField(default=False)
create_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username + ' - ' + self.name + ': ' + str(self.balance)
1 => 我希望能够输入端点 /api/users/accounts/omarjandlai
并使用 omarjandali 用户外键
2 => 我希望能够输入以下内容
api/users/accounts/
和 return 数据库中的所有帐户
我尝试了 4 - 5 种不同的方法来让它工作,但我无法让它工作。
这是我的序列化程序和视图
序列化程序:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('user', '_id', 'name', 'balance', 'currency', 'bank_name',
'routing', '_class', 'type', 'active', 'main', 'synapse')
观看次数:
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('user',)
发生的事情是,当我执行
api/users/account
我看到了所有的账户
api/users/account/omarjandali
我得到 detail not found
网址:
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = router.urls
我可以看到您正在使用 DefaultRouter 的默认功能。这样您只能使用他们的主键访问记录详细信息。由于您没有明确指定任何字段作为主键 (primary=True
),Django 设置字段 id,即 PositiveIntegerField
作为模型的主键。因此,如果您想访问记录的详细信息,则必须使用 api/users/account/112/
.
您可以使用过滤器按名称访问记录:api/users/account/?search='omarjandali'
,但您需要添加 SearchFilter
。
from rest_framework.filters import SearchFilter
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend, SearchFilter)
filter_fields = ('user',)
search_fields = ('name',)
如果你想坚持 url 模式 api/users/account/omarjandali/
,你必须将它添加到 urls.py 并使用另一个视图集为了让原始路由器根据 DefaultRouter 定义运行:
urls.py:
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = [
path('', include(router.urls)),
path('api/users/account/<str:username>/', views.GetRecordsByNameViewSet.as_view({'get': 'list'}),
]
views.py
from rest_framework.response import Response
class GetRecordsByNameViewSet(viewsets.ViewSet):
def list(self, request, username):
accounts = Account.objects.filter(user__username=username)
accounts_to_return = AccountSerializer(accounts, many=True).data
return Response(accounts_to_return)
您可以尝试覆盖
get_queryset (method)
这样就无需在 URL 中提供 username/email。你会做 localhost8000/accounts,它只会显示相应用户的帐户。
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all();
serializer_class = AccountSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('user',)
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(user=self.request.user)
return queryset
注意:如果在项目中设置了身份验证,这将起作用。在令牌认证的情况下,您需要在授权中提供令牌 header.