-1

I am working with django and javascript, and I need to send a JSON of a dictionary to javascript. This needs to combine two different django queryset into a dictionary like object

I tried:

from itertools import chain
import json
checkin = Checkins.objects.get(checkinno=1)
checksins = (Checkins.objects.filter(checkinno=1).values('checkinno', 'date', 'time', 'consulted', 'closed'))
custid = checkin.hospitalid.cstid
checks = (customer.objects.filter(cstid=custid).values('name', 'age', 'gender', 'mobile', 'email', 'address'))
result_list = list(chain(checksins, checks))
print(result_list)

I get:

[{
    'checkinno': 1,
    'date': datetime.date(2018, 9, 10), 
    'time': '6:10 PM', 
    'consulted': 0,
    'closed': 0
}, 
{
    'name': 'Jeff',
    'age': 5, 
    'gender': 'male',
    'mobile': '000000',
    'email': '', 'address': ''
}]

What I want:

[
    'checkinno': 1,
    'date': datetime.date(2018, 9, 10),
    'time': '6:10 PM',
    'consulted': 0, 
    'closed': 0,
    'name': 'Jeff',
    'age': 5, 
    'gender': 'male',
    'mobile': '000000', 
    'email': '', 
    'address': ''
]
Joel G Mathew
  • 7,561
  • 15
  • 54
  • 86
  • 2
    The syntax of the second is a bit off: the syntax "combines" lists and dictionaries. – Willem Van Onsem Sep 10 '18 at 14:31
  • Furthermore what should happen if the two (or more) dictionaries share the same key? Since a Python dictionary maps a key to *one* value, this can result in a lot of trouble. – Willem Van Onsem Sep 10 '18 at 14:32
  • They wont share the same key. It's a django model with the second related to the first by foreign key – Joel G Mathew Sep 10 '18 at 14:33
  • Please clarify whether you need this done without evaluating the query or not. – wim Sep 10 '18 at 14:33
  • Well it is strictly speaking possible that you have a `City` and a `Country` that both have a `name` attribute. So the fact that those are related through an `FK` does not solve the matter. – Willem Van Onsem Sep 10 '18 at 14:35
  • @wim I do need the query evaluated. The final object is to generate a JSON which can be read by javascript – Joel G Mathew Sep 10 '18 at 14:36
  • That being said, I think it might be better to use an `annotate` here, this will result in performing a single query. – Willem Van Onsem Sep 10 '18 at 14:36
  • @WillemVanOnsem Actually one is a customer model, which contains details about a person. The other one is a model which stores only a checkin number, a date and time, which represents at what time the patient was registered at the hospital. – Joel G Mathew Sep 10 '18 at 14:37
  • Another problem that we might be facing here is that there can be *multiple* `customer` for a given `hospital`, so that can result in the fact that the second returns *multiple* dictionaries, and the "duplicate" key issue thus persists. – Willem Van Onsem Sep 10 '18 at 14:37
  • @WillemVanOnsem The checkinno is a unique primary key which has a one-on-one relation a table of customers – Joel G Mathew Sep 10 '18 at 14:39
  • how do you expect to have a list that has keys and values? Python does not support such a list – Onyambu Sep 10 '18 at 15:23
  • @Onyambu You mean I should have used a dictionary? But I get an error `dictionary update sequence element #0 has length 5; 2 is required` when I try dict of that queryset – Joel G Mathew Sep 10 '18 at 15:24
  • sorry mate, there is no list that supports a key-value relationship try doing `['a':3]` and see what happens – Onyambu Sep 10 '18 at 15:27
  • `{j:k for i in result_list for j,k in i.items()}` should give you an idea of what you want. BUT THIS IS VERY WRONG – Onyambu Sep 10 '18 at 15:29
  • By any chance, any of those is what you're trying to achieve? [1](https://stackoverflow.com/questions/6164604/serialize-django-models-with-reverse-one-to-one-fields-to-json), [2](https://stackoverflow.com/questions/30548337/serialize-objects-with-one-to-one-relationship-django), [3](https://stackoverflow.com/questions/39152899/whats-the-best-way-to-serialize-more-than-one-model-to-json-in-django-1-6) – Rodrigo Rodrigues Sep 10 '18 at 15:40

3 Answers3

0

Could you just use for this a = {**b, **c} for result_list?

Where a is result_list and b/c represent the dictionaries you wish to merge.

vash_the_stampede
  • 4,590
  • 1
  • 8
  • 20
0

If you are using django-rest-framework for making the API, the docs say how to get it done:

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ('name', 'age', 'gender', 'mobile', 'email', 'address')

class CheckinsSerializer(serializers.ModelSerializer):
    custid = CustomerSerializer(read_only=True)

    class Meta:
        model = Checkins
        fields = ('checkinno', 'date', 'time', 'consulted', 'closed', 'custid')

Then you test I with:

>>> checkin = Checkins.objects.get(checkinno=1)
>>> serializer = CheckinsSerializer(instance=checkin)
>>> serializer.data
Rodrigo Rodrigues
  • 7,545
  • 1
  • 24
  • 36
-1

I solved my problem like this. I'm sure there is a more pythonic way of doing this.

from itertools import chain
checkin = Checkins.objects.get(checkinno=1)
checksins = (Checkins.objects.filter(checkinno=1).values('checkinno', 'date', 'time', 'consulted', 'closed'))
custid = checkin.hospitalid.cstid
checks = (customer.objects.filter(cstid=custid).values('name', 'age', 'gender', 'mobile', 'email', 'address'))
result_list = list(chain(checksins, checks))
res = {**result_list[0], **result_list[1]} 
print(res)

Output:

{'checkinno': 1, 'date': datetime.date(2018, 9, 10), 'time': '6:10 PM', 'consulted': 0, 'closed': 0, 'name': 'Jeff', 'age': 5, 'gender': 'male', 'mobile': '8610651871', 'email': '', 'address': ''}
Joel G Mathew
  • 7,561
  • 15
  • 54
  • 86