Django 过滤器也可以获取反向外键,或者更好的方式来组合相关的数据库信息?
Django filter that also grabs a reverse ForeignKey, or better way to combine associated database info?
我正在做一些后端 Django 工作,需要我通过过滤获取 Employee
,但我还需要获取与 Employee
关联的 EmployeeAddress
对象.我想知道这是否可以在单个查询中实现。我需要将员工地址和员工信息放在一个组合的单个字典中,以便在前端使用 JS 访问。
我有这样的模型,
Class Employee(models.model):
first_name
last_name
email
Class EmployeeAddress(models.model):
employee = models.ForeignKey(Employee):
street
city
state
我有一个观点,有点做这个工作,但是在将两个单独的 QuerySets 合并到一个包含所有值的列出的字典中时遇到了问题。
我希望有一种方法可以获取 EmployeeAddress
而无需编写第二个查询,而只需在第一个 employee_list
查询中获取相关数据?
def employee_ajax_list(request):
email = request.GET.get('email', None)
employee_list = Employee.objects.filter(email=email)
employee_address = EmployeeAddress.objects.filter(employee_id__in=employee_list).values(
'street', 'city', 'state',)
# this chain kinda works, but splits them into 2 separate dictionaries?
employee_info = list(chain(employee_list.values(), employee_address))
data = {
'employee_list': employee_info
}
return JsonResponse(data)
只是在寻找一些建议,让这项工作更顺利一些!
也许像这样的东西在单个查询中会更好一些:
employee_info = EmployeeAddress.objects.filter(employee__email=email).values("employee__email", "employee__<another_field>", "street", "city", "state")
data = {
'employee_list': employee_info
}
最好的方法是使用 DRF 序列化程序:
class EmployeeAddressSerializer(serializers.ModelSerializer):
class Meta:
fields = "__all__"
model = Employee
class EmployeeSerializer(serializers.ModelSerializer):
# you should add related_name="addresses" in the
# foreignkey if you want this works.
addresses = EmployeeAddressSerializer(many=True)
class Meta:
fields = "__all__"
model = Employee
然后使用:
employee = Employee.objects.filter(email=email).last()
return JsonResponse(EmployeeSerializer(employee).data)
更改此行
employee = models.ForeignKey(Employee)
到
employee = models.ForeignKey(Employee, related_name="address")
这样您就可以通过在常规代码中执行 employee.address
或在查询中执行 employee__address
来访问员工的地址。
例如:
Employee.objects
.filter(email=email)
.exclude(address=None)
.values(
'email',
'name',
'address__street',
'address__city',
'address__state'
)
(.exclude()
子句是为了防止有人没有设置地址。)
应该输出如下内容:
<QuerySet [{'email': 'johnsmith@example.com',
'name': 'John Smith', 'address__street':
'123 Maple St', 'address__city': 'Springfield',
'address__state': 'MO'}]>
我正在做一些后端 Django 工作,需要我通过过滤获取 Employee
,但我还需要获取与 Employee
关联的 EmployeeAddress
对象.我想知道这是否可以在单个查询中实现。我需要将员工地址和员工信息放在一个组合的单个字典中,以便在前端使用 JS 访问。
我有这样的模型,
Class Employee(models.model):
first_name
last_name
email
Class EmployeeAddress(models.model):
employee = models.ForeignKey(Employee):
street
city
state
我有一个观点,有点做这个工作,但是在将两个单独的 QuerySets 合并到一个包含所有值的列出的字典中时遇到了问题。
我希望有一种方法可以获取 EmployeeAddress
而无需编写第二个查询,而只需在第一个 employee_list
查询中获取相关数据?
def employee_ajax_list(request):
email = request.GET.get('email', None)
employee_list = Employee.objects.filter(email=email)
employee_address = EmployeeAddress.objects.filter(employee_id__in=employee_list).values(
'street', 'city', 'state',)
# this chain kinda works, but splits them into 2 separate dictionaries?
employee_info = list(chain(employee_list.values(), employee_address))
data = {
'employee_list': employee_info
}
return JsonResponse(data)
只是在寻找一些建议,让这项工作更顺利一些!
也许像这样的东西在单个查询中会更好一些:
employee_info = EmployeeAddress.objects.filter(employee__email=email).values("employee__email", "employee__<another_field>", "street", "city", "state")
data = {
'employee_list': employee_info
}
最好的方法是使用 DRF 序列化程序:
class EmployeeAddressSerializer(serializers.ModelSerializer):
class Meta:
fields = "__all__"
model = Employee
class EmployeeSerializer(serializers.ModelSerializer):
# you should add related_name="addresses" in the
# foreignkey if you want this works.
addresses = EmployeeAddressSerializer(many=True)
class Meta:
fields = "__all__"
model = Employee
然后使用:
employee = Employee.objects.filter(email=email).last()
return JsonResponse(EmployeeSerializer(employee).data)
更改此行
employee = models.ForeignKey(Employee)
到
employee = models.ForeignKey(Employee, related_name="address")
这样您就可以通过在常规代码中执行 employee.address
或在查询中执行 employee__address
来访问员工的地址。
例如:
Employee.objects
.filter(email=email)
.exclude(address=None)
.values(
'email',
'name',
'address__street',
'address__city',
'address__state'
)
(.exclude()
子句是为了防止有人没有设置地址。)
应该输出如下内容:
<QuerySet [{'email': 'johnsmith@example.com',
'name': 'John Smith', 'address__street':
'123 Maple St', 'address__city': 'Springfield',
'address__state': 'MO'}]>