How to send multiple query sets in django? - django

I have created a views function in django which returns the data of all influencers. Now I want to add the functionality that a user can make multiple lists and then add those influencers to any of the list created by them. The lists created by the users are displayed in the form of a drop down menu in front of the influencers name. How should I create the API so that the list created by the users are displayed in front of the influencers.
P.S: I want to create the API without using django rest framework.
This is what I have tried till now:
def index(request):
influencers = Influencer.objects.all()
influencer_data = serializers.serialize("json",influencers)
user_list = UserList.objects.all().filter(user_id = request.user.id)
user_list = serializers.serialize("json",user_list)
context = {
'influencer_data':influencer_data,
'user_list':user_list,
}
return HttpResponse(json.dumps(context),content_type='application/json')
I am getting the result as:
{"influencer_data": "[{\"model\": \"influencer_listings.influencer\", \"pk\": 8794, \"fields\": {\"full_name\": \"F A I Z S H A I K H \\ud83c\\udf08\", \"username\": \"mr_faizzz_07\", \"photo\": \"\", \"email_id\": \"\", \"external_url\": \"\
.............................
.............................
"user_list": "[{\"model\": \"user_listings.userlist\", \"pk\": 21, \"fields\": {\"user_id\": 5, \"list_name\": \"Campaign 1\"}}, {\"model\": \"user_listings.userlist\", \"pk\": 22, \"fields\": {\"user_id\": 5, \"list_name\": \"Delhi Campaign\"}}]"}
The return statement makes the JSON object returned a string.I want the data to be returned in the JSON format.

from itertools import chain
from django.http import HttpResponse
from django.core import serializers
def index(request):
user_list = UserList.objects.all().filter(user_id=request.user.id)
influencers = Influencer.objects.all()
queryset = list(chain(user_list, influencers ))
ser_query = serializers.serialize('json', queryset)
return HttpResponse(ser_query)
Do it like this, modify the code to your needs

Related

How to update existing data and create new one django base command?

i am trying to store data in from json file and i added its not a problem to add data but when i trigger data again again they copy data and create same new one that i don't want , i want that it will update existing data and if there will new data in json file it will add in model .
here is my django base command code.
from django.core.management.base import BaseCommand
import requests
from demo.models import CoronaAge, CoronaSex, CoronaComorbidity
class Command(BaseCommand):
def handle(self, *args, **kwargs):
url = 'https://api.the2019ncov.com/api/fatality-rate'
r = requests.get(url)
titles = r.json()
print(titles)
# For between age
for title in titles['byAge'] or []:
CoronaAge.objects.update_or_create(
age=title['age'],
rate=title['rate']
)
context = {'titles': CoronaAge.objects.all()}
# for sex wise male and female
for title in titles['bySex'] or []:
CoronaSex.objects.update_or_create(
sex=title['sex'],
rate=title['rate']
)
context = {'titles': CoronaSex.objects.all()}
for title in titles['byComorbidity'] or []:
CoronaComorbidity.objects.update_or_create(
condition=title['preExistingCondition'],
rate=title['rate']
)
context = {'titles': CoronaComorbidity.objects.all()}
This is how I would solve it. Get a list existing data. Then, for each new entry check if it exists in the db, create new object, add to list and at the end run bulk_create to insert all of them in one hit. If exists, then update all fields that you want and again, run bulk update at the end.
corona_ages = CoronaAge.objects.all()
new_ages = []
existing_ages = []
for title in titles['byAge'] or []:
entry = corona_ages.filter(age=title['age']).first():
if not entry:
new_data = CoronaAge(**title)
new_ages.append(new_data)
else:
entry['some_param'] = title['some_param']
entry['other_param'] = title['other_param']
existing_ages.append(new_date)
CoronaAge.objects.bulk_create(new_ages)
CoronaAge.objects.bulk_update(existing_ages)

'list' object has no attribute 'json'

I'm trying to fetch all the products from the firebase database, but in the json data form.
Here's the structure of my database:
products{
0{
name:...
price:...
}
1{
name:..
price:..
and so on. And below is the code I tried:
import json
from .models import Product
import pyrebase
def get_products():
database = firebase_key().database()
product_list = Product.objects.all()
r = database.child("products").get().each()
jsonList = r.json()
jsonData = jsonList['products']
data = []
for products in r:
productData = {}
productData['name'] = products.name
productData['image'] = products.image
productData['price'] = products.price
productData['description'] = products.description
data.append(productData)
return data
I'm new to both django and firebase, so any help would be appreciated
As #Kevin pointed out the each does not return a json, but a list. You can check it out on the pyrebase documentation.
Your code should probably look like this:
all_products = database.child("products").get()
for product in all_products.each():
data.append(product.val()) # This works if your fields have the same names.
Edit
If you still need data as a JSON.
json_data = json.dumps(data)

How to generate a Word document using Django

I'm new to Django and would like to create a form where users can input some data, and have a Word document be created for download.
I was using the templated-docs library (https://pypi.org/project/templateddocs/) to accomplish this task, but I'm receiving an error.
in my views.py:
from templated_docs import fill_template
from templated_docs.http import FileResponse
def get_document(request):
"""
A view to get a document filled with context variables.
"""
context = {'user': request.user} # Just an example
filename = fill_template('sample.odt', context, output_format='pdf')
visible_filename = 'greeting.pdf'
return FileResponse(filename, visible_filename)
After the user inputs information in the form, I'm getting this error:
get_template_sources() takes 2 positional arguments but 3 were given
the error is produced from the variable that's in views.py:
filename = fill_template('sample.odt', context, output_format='pdf')
The library was written 3 years back and no longer seems to be maintained.
It used LibreOffice via pylokit for parsing source and generating output.
Alternatively you can use Pandoc (universal document converter) + Pandoc Filters for parsing source, doing modifications and generating output.
The whole of the above code can be accomplished with something like below.
import io
import pypandoc
import panflute as pf
from django.http import FileResponse
def generate_invoice(request):
template = 'files/invoice.docx'
output_path = '/tmp/invoice - {}.pdf'.format(request.user.id)
context = {
'{{name}}': 'Foo'
}
# parse input file
data = pypandoc.convert_file(template, 'json')
f = io.StringIO(data)
doc = pf.load(f)
# do replacements
for key, value in context.items():
doc = doc.replace_keyword(key, pf.Str(value))
# generate output
with io.StringIO() as f:
pf.dump(doc, f)
contents = f.getvalue()
pypandoc.convert_text(contents, 'pdf', format='json', outputfile=output_path)
return FileResponse(open(output_path, 'rb'), filename='invoice.pdf')

Django WeasyPrint - Export filtered list

So I've created a pdf file from a ListView called "OrderListView". Now I would like to pass a queryset to the pdf file.
I rewrote my listview as a function view for more clarity. I need to find a way to pass the queryset to the pdf view. I'm using django-filter to create the filtered view. I have the following;
filters.py
class OrderFilter(django_filters.FilterSet):
class Meta:
model = Order
fields = {
'start_date': ['gte'],
'end_date': ['lte'],
}
views.py
from .filters import *
# View to show a filtered list using django-filter
def order_list(request):
order_list = Order.objects.all()
order_filter = OrderFilter(request.GET, queryset=order_list)
start_date__gte = request.GET.get('start_date__gte','')
start_date__lte = request.GET.get('start_date__lte','')
return render(request, 'orders/order_list.html', {
'filter': order_filter,
'start_date__gte': start_date__gte,
'start_date__lte': start_date__lte,
})
# View to create a pdf file from the filtered view using WeasyPrint
def order_list_pdf(request):
# Edited: Create queryset
start_date__gte = request.GET.get('start_date__gte','')
start_date__lte = request.GET.get('start_date__lte','')
order_list = Order.objects.filter(
Q(start_date__gte=start_date__gte) |
Q(start_date__lte=start_date__lte)
)
order_filter = OrderFilter(request.GET, queryset=order_list)
response = HttpResponse(content_type="application/pdf")
response['Content-Inline'] = 'attachment; filename=filtered_list.pdf'.format()
html = render_to_string('pdf/pdf_booking_list_arrivals.html', {
'filtered_list': order_list,
})
font_config = FontConfiguration()
HTML(string=html).write_pdf(response, font_config=font_config)
return response
So I have tried using
start_date__gte = request.GET.get('start_date__gte','')
start_date__lte = request.GET.get('start_date__lte','')
And pass the query with the url
#edited
<a class="btn" href="{% url 'order_list_pdf' %}?start_date__gte={{ start_date__gte }}&start_date__lte={{ start_date__lte }}">Create PDF</a>
This does create the query in the url but does not filter the list. The generated pdf is working, I just need to find a way to only send the filtered results to the pdf view.
Any help would be appreciated!

JsonResponse with model instance including M2M

It seems that you cannot replace
from django.core import serializers
from django.http import HttpResponse, JsonResponse
qs = MyModel.objects.filter(pk=1)
data = serializers.serialize('json', qs, fields=('id', 'name', 'my_m2m_field'))
# I want data of the one instance only.
data = data[data.find('{', 3, 15):data.rfind('}', -60, -3) + 1]
return HttpResponse(data, content_type='application/json')
by JsonResponse, can you? (I don't mean to replace just the last line by return JsonResponse(data) for this doesn't make sense in my opinion.)
For this results in an error:
my_m2m_ids = qs[0].my_m2m_field.all().values_list('id', 'flat=True') # = [3, 2]
dic = {'my_m2m_ids': my_m2m_ids} # also tried `my_m2m_ids[:]`
dic.update(qs.values('id', 'name')[0]) # also tried `list(qs.`… and `dict(qs.`…
return JsonResponse(dic) # also tried `safe=False`
Error: TypeError at <path> [3, 2] is not JSON serializable. I don't know exactly why but I think it's caused somehow by the ValuesQuerySet retruned by values() or by the ValuesListQuerySet returnd by values_list().
Is there any better/shorter solution? For I think it's both not ideal.
Update
It works after converting the ValuesListQuerySet to a list (by my_m2m_ids = list(my_m2m_ids), but my_m2m_ids[:] obviously doesn't work).
But I still loved to be able to use JsonResponse like this:
return JsonResponse(MyModel.objects.get(pk=1).only('id', 'name', 'my_m2m_field)) (or similar).