我正在使用Django REST框架配置针对不同服务使用不同登录名进行的实验。如何根据所选服务调整BasicLogins集合的查询集。
配置实验时,您选择了服务和多个参与的BasicLogins。 有一些与BasicLogin相关的特定登录名。假设我们有BasicLogin,ALogin,BLogin和CLogin。对于给定的BasicLogin,可能并非所有特定的登录名都存在,例如
BasicLogin有一个supports方法,该方法可以查找与特定于服务的登录名是否相关。如果存在此类特定的Login对象,则BasicLogin对象支持给定的Service。
class BasicLogin(models.Model):
name = models.CharField(max_length=25)
password = models.CharField(max_length=25)
disabled = models.BooleanField(default=False, blank=True)
def supports(self, service_name):
""" Returns whether a specific Login for a given service is available for a BaseLogin object."""
if service_name == "a":
return ALogin.objects.filter(basic_account=self) is not None
elif service_name == "b":
return BLogin.objects.filter(basic_account=self) is not None
elif service_name == "c":
return CLogin.objects.filter(basic_account=self) is not None
ExperimentSerializer可以轻松用于过滤已启用的BasicAccounts。
class class ExperimentSerializer(serializers.HyperlinkedModelSerializer):
service = serializers.HyperlinkedRelatedField(
queryset=Service.objects.all(), many=False, view_name="service-detail"
)
basic_logins = serializers.HyperlinkedRelatedField(
view_name="basiclogin-detail",
many=True,
read_only=False,
queryset=BasicAccount.objects.filter(disabled=False)
# ^ Here is where I'd like to only show BasicLogins that support the service
# if possible by using the "supports" method of BasicLogin
)
我可以在ExperimentSerializer中过滤BasicLogin RelatedField
的查询集,使其仅包含具有给定服务的相应特定登录名的BasicLogins吗?
例如在显示的图片中选择了服务“ A ”,因此仅应显示具有相应 A 登录名的BasicLogins。
以下是完整代码示例:
from django.db import models
######## MODELS
### Service model
class Service(models.Model):
name = models.CharField(max_length=64, blank=False, null=False)
### Basic login model containing general information
class BasicLogin(models.Model):
name = models.CharField(max_length=25)
password = models.CharField(max_length=25)
disabled = models.BooleanField(default=False, blank=True)
def supports(self, service_name):
""" Returns whether a specific Login for a given service is available for a BaseLogin object."""
if service_name == "a":
return ALogin.objects.filter(basic_account=self) is not None
elif service_name == "b":
return BLogin.objects.filter(basic_account=self) is not None
elif service_name == "c":
return CLogin.objects.filter(basic_account=self) is not None
### Specific models for different services
class ALogin(models.Model):
a_id = models.CharField(max_length=64) # exemplary
basic_login = models.OneToOneField(BasicLogins, related_name="a_account")
class BLogin(models.Model):
b_id = models.CharField(max_length=64) # exemplary
b_api_hash = models.CharField(max_length=64) # exemplary
basic_login = models.OneToOneField(BasicLogins, related_name="b_account")
class CLogin(models.Model):
c_password = models.CharField(max_length=64) # exemplary
basic_login = models.OneToOneField(BasicLogins, related_name="c_account")
### Model combining the previous models
class Experiment(models.Model):
basic_logins = models.ManyToManyField(BasicLogins, "experiments")
service = models.ForeignKey(Service, related_name="experiments")
######## SERIALIZERS
class class ExperimentSerializer(serializers.HyperlinkedModelSerializer):
service = serializers.HyperlinkedRelatedField(
queryset=Service.objects.all(), many=False, view_name="service-detail"
)
basic_logins = serializers.HyperlinkedRelatedField(
view_name="basiclogin-detail",
many=True,
read_only=False,
queryset=BasicAccount.objects.filter(disabled=False) # <--- Here is where I'd like to only show BasicLogins that support the service using the "supports" method
)