Я использую Django REST Framework для настройки экспериментов, которые проводятся с использованием разных имен входа для разных служб. Как настроить набор запросов из набора BasicLogins в зависимости от выбранной службы.
Контекст
При настройке эксперимента вы выбрали службу и несколько участвующих BasicLogins. Есть определенные c логины, которые 1-к-1 связаны с BasicLogin. Допустим, у нас есть BasicLogin, ALogin, BLogin и CLogin. Может случиться, что не все указанные c логины существуют для данного BasicLogin, например,
- BasicLogin 1 : имеет связанные логины для сервисов A и B
- BasicLogin 2 : связанные логины для службы C
- BasicLogin 3 : имеет соответствующие логины для служб A , B , C

BasicLogin имеет метод support, который ищет, связан ли с ним логин, указанный в Service c. Если такой специфицированный c объект Login существует, объект BasicLogin поддерживает данную службу.
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 можно легко использовать для фильтрации включенных базовых учетных записей.
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
)
Вопрос
Можно ли отфильтровать набор запросов BasicLogin RelatedField
в ExperimentSerializer, чтобы он содержал только BasicLogins с соответствующим указанным c логином для данной службы?
, например, на показанном рисунке Сервис " A " выбран, поэтому должны отображаться только BasicLogins с соответствующим A логином.
Вот пример с полным кодом :
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
)