[英]Django model instance fields with ManyToMany relationship to Dict
我正在嘗試創建一個簡單的操作,該操作從數據庫中獲取一條記錄(具有ManyToMany關系),然后顯示JSON序列化實例,這是我目前的操作方式:
服務模式:
class SystemService(models.Model):
name = models.CharField(max_length=35, unique=True, null=False, blank=False)
verion = models.CharField(max_length=35, unique=True, null=False, blank=False)
def __str__(self):
return self.name
服務器型號:
class Server(models.Model):
name = models.CharField(max_length=35, unique=True, null=False, blank=False)
ip_address = models.GenericIPAddressField(protocol='both', unpack_ipv4=True,
null=False, blank=False, unique=True)
operating_system = models.ForeignKey(OperatingSystem, null=False, blank=False)
monitored_services = models.ManyToManyField(SystemService)
info = models.CharField(max_length=250, null=True, blank=True)
pause_monitoring = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
這就是現在使用muj-gabriel答案的方式:
def get_server(request, server_id):
try:
server_object = Server.objects.get(id=server_id)
data = {
'name': server_object.name,
'ip_address': server_object.ip_address,
'os': server_object.operating_system.name,
'info': server_object.info,
'monitoring_paused': server_object.pause_monitoring,
'created_at': server_object.created_at,
'update_at': server_object.updated_at,
'services': {service['id']: service['name'] for service
in server_object.monitored_services.values('id', 'name')}
}
return JsonResponse(data)
except Server.DoesNotExist:
return JsonResponse({'error': 'Selected object does not exits!'})
我認為我所做的工作不夠好,因為每次我需要獲取一個實例作為JSON時都必須重復相同的事情,所以我想知道是否存在一種pythonic和動態的方式來做到這一點?
如果您只需要值'id'和'name',我建議使用以下方法:
'services': {service['id']: service['name']
for service in server_object.monitored_services.values('id', 'name')}
參見Django文檔
您也可以將代碼移到Model類的屬性中,以在其他地方重用。
class Server(models.Model):
.......
@property
def data(self):
return {
'name': self.name,
'ip_address': self.ip_address,
'os': self.operating_system.name,
'info': self.info,
'monitoring_paused': self.pause_monitoring,
'created_at': self.created_at,
'update_at': self.updated_at,
'services': {service['id']: service['name'] for service in self.monitored_services.values('id', 'name')}
}
您的查看功能將是:
def get_server(request, server_id):
try:
server_object = Server.objects.get(id=server_id)
return JsonResponse(server_object.data)
except Server.DoesNotExist:
return JsonResponse({'error': 'Selected object does not exits!'})
在Django文檔中查看了一下之后,我發現了model_to_dict函數,該函數基本上可以完成我需要的任務(將Model實例轉換為Dict),但是對於ManyToMany關系,它僅返回PK列表,因此我基於該函數編寫了自己的函數:
def db_instance2dict(instance):
from django.db.models.fields.related import ManyToManyField
metas = instance._meta
data = {}
for f in chain(metas.concrete_fields, metas.many_to_many):
if isinstance(f, ManyToManyField):
data[str(f.name)] = {tmp_object.pk: db_instance2dict(tmp_object)
for tmp_object in f.value_from_object(instance)}
else:
data[str(f.name)] = str(getattr(instance, f.name, False))
return data
希望它可以幫助別人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.