2016-05-23 5 views
0

データベースからManyToMany関係で1つのレコードを取得してJSON直列化インスタンスを表示する単純なアクションを作成しようとしています。DictへのManyToMany関係のDjangoモデルインスタンスフィールド

サービスモデル:

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-ガブリエルの答えを使用している方法です。

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として1つのインスタンスを取得する必要があるたびに繰り返す必要があるため、私は私がやったことは十分であるとは思わないので、私はニシキヘビがあるかどうかを知りたいとそれを行うための動的な方法?

答えて

0

Djangoのドキュメントにビットを見た後、私は基本的に私は(Dictのためにモデルのインスタンス)が必要に何model_to_dict機能を、見つけましたが、用多対多の関係はそれだけの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 

は、それが他の誰かに役立ちます願っています。

1

あなたはちょうど私がこれを使用することをお勧め値「ID」と「名前」を必要とする場合:

'services': {service['id']: service['name'] 
      for service in server_object.monitored_services.values('id', 'name')} 

django docs

を参照してください。また、あなたは再利用するモデルクラスにプロパティにコードを移動することができますそれはどこかで。

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!'}) 
+0

答えのためのThanxコードを改善するために使用しましたが、毎回同じことを繰り返したくないと言ったときに、私は他のモデルを意味していました。どのモデルのインスタンスでも使用できます。 – ddalu5

+1

私が返答で言ったように、Modelクラスで@propertyを作成してコード –

+0

を移動すると、別のモデル(Serverだけではありません)のインスタンスを意味します。 – ddalu5

関連する問題