django data not changing dynamically - python

I wrote a django application to display some data fetched from mongodb in html template. All the order item ids are fetched with status 'APPROVED'
models.py:
from pymongo import MongoClient
class GetNewOrders(object):
def __init__(self):
self.client = MongoClient('localhost',27017)
self.db = self.client['Flipkart']
self.sale_order = list(self.db['sale_order'].find({'status':'APPROVED'}))
def getOrderItemId(self):
oiids = []
for each in self.sale_order:
oiids.append(each['orderItemId'])
return oiids
views.py:
from django.shortcuts import render
from django.http import HttpResponse
from orders.models import GetNewOrders
no = GetNewOrders()
oiids_new = no.getOrderItemId()
def orders(request):
context_dict = {'oiids_new':oiids_new}
return render(request, 'orders/orders.html', context_dict)
i used a for loop in my html file to display that data. If i change the status of a document to 'APPROVED', it does not reflect in my html until i restart the server. How to show the changed data in html without restarting django server?

because GetNewOrders is at module level it is only executed once - you need to move it into the function body:
def orders(request):
no = GetNewOrders()
oiids_new = no.getOrderItemId()
context_dict = {'oiids_new':oiids_new}
return render(request, 'orders/orders.html', context_dict)

Related

How can I return a context from views.py in different html files in Django?

So, I have a method called 'room' in my views.py file.
I can only access this room on my room.html page as I'm returning it there but I would like to use this data on my index page as well.
How can I do that?
Views.py
def room(request):
rooms = Rooms.objects.all()
photos = RoomImage.objects.all()
context = {'rooms':rooms, 'photos':photos}
return render(request, 'hotelbook/room.html', context)
You can do one thing, just create a simple utility function in views.py for getting all rooms.
create utils.py file in django application:
# utils.py
def get_all_rooms():
all_rooms = Room.objects.all()
all_photos = RoomImage.objects.all()
return {"rooms": all_rooms, "photos": all_photos}
Then, import utils in views.py file
# views.py
from .utils import get_all_rooms
data = get_all_rooms()
def room(request):
return render(request, "room.html", {"data": data})
def index(request):
return render(request, "index.html", {"data": data})
This can be very efficient as we are calling cahced result instead of firing new db query!
I can only access this room on my room.html page as I'm returning it there but I would like to use this data on my index page as well.
Just pass Rooms.objects.all() also in that view which renders the index.html template.
Below is an example.
def index(request):
rooms = Rooms.objects.all()
photos = RoomImage.objects.all()
context = {'rooms':rooms, 'photos':photos}
return render(request, 'hotelbook/index.html', context)
Now, you can also use rooms in index.html template.

How to link between django views components

Actually, I am pretty new in Django. I have created three views in my views.py.
This is my following code in views.py :
from django.shortcuts import render
import pymongo
from .models import *
from .serializers import *
from .forms import *
from .codes.scraping import scrap
def home_view(request):
context = {}
context ['form'] = Scraping()
return render(request,'home.html',context)
def loading_view(request):
return render(request,'loading.html')
def datatable_view(request):
client = pymongo.MongoClient("mongodb://localhost:27017/")
db= client["aliexpress_db"]
col = db["segment"]
products = col.find()
context = {'products' : products}
return render(request,'datatable.html', context)
My question is that I want to get a method in order to get the home_view first then my loading_view while the scraping is processing then my datatable_view.
I don't know how to link between these views. I am completely beginner. Any help would be great.
this is not a job for Django. I think what you want to do is possible through these steps:
place your loading gif/vector animation in your home_view
when the user submits the form show this animation using some javascript code until you get a response from datatable_view and change the page
pass the results to the template of datatable_view to render them.
alternatively, you can use an AJAX Call to receive the results in the home view.
checking out this answer would also help.

How to retrieve data from an existing db file and display it on webpage using Django?

This is the views.py file:
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import Report
import random
class HomePageView(TemplateView):
def get(self, request, **kwargs):
args = {}
data = Report.objects.all()
args['data'] = data
return render(request, 'index.html',args)
I'm finding it difficult to understand the framework since I'm a beginner. So please help me.
You are trying to use class base view which will be different from function base view, to pass context data to template in class base view you need to override get_context_data method as below:
class HomePageView(TemplateView):
""" Home page view """
template_name = "index.html"
def get_context_data(self, **kwargs):
# first of all calling it's parent class method to get context (if any)
context = super(HomePageView, self).get_context_data(**kwargs)
# now you can update context dictionary as below:
context['data'] = Report.objects.all()
return context
Now you can access data in your template using {{ data }}
You can display the FileField content by passing the following
{{ context_obj.file_field_name.url }} in the template.

How to pass a query set to the context class in Django?

I am trying to pass a queryset object to django context class, but doing so results in the following error: TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
Now i understand that the context accepts only a dictionary but i am following an example from a book called django_unleashed which uses Django version 1.8 and i am using django 2.0. and i guess it was done like that in previous versions.
So my question is how should i do this step correctly using django 2.0
from django.shortcuts import render
from django.http import HttpResponse
from .models import Tag
from django.template import Context, loader
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = Context({'tag_list': tag_list})
output = template.render(context)
return HttpResponse(output)
As the error suggests, you should use a regular dictionary for the context:
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = {'tag_list': tag_list}
output = template.render(context)
return HttpResponse(output)
In practice, you would usually use the render shortcut rather than manually rendering the template:
from django.shortcuts import render
def homepage(request):
tag_list = Tag.objects.all()
context = {'tag_list': tag_list}
return render(request, 'organizer/tag_list.html', context)
'''you have a model class named 'Tag',
wish your template is on ' Project directory/ app directory/ template/ same name of app directory'
example: let your project name is 'Website' and app name is 'organizer' then the template will be on: 'Website/ organizer/ templates/ organizer/ tag_list.html' Confirm your TEMPLATES setting is default on setting.py file."'
from django.shortcuts import render
from .models import Tag
def homepage(request):
tag_list = Tag.objects.all()
context = { 'tag_list' : tag_list}
return render ( request, 'organizer/tag_list.html', context)

'QueryDict' object has no attribute 'id'

On the 'panel' page, I have a choice field with a list of uploaded documents or 'bots' as I usually refer to them. This list only displays 'bots' that have been uploaded by the current user.
panel\forms.py
from django import forms
import os
from upload.models import Document
#### RETRIEVE LIST OF BOTS UPLOADED BY CURRENT USER ####
def get_files(user):
bots = Document.objects.filter(user=user.id)
file_list = []
for b in bots:
file_list.append((b.id,b.docfile))
return file_list
class botForm(forms.Form):
def __init__(self, user, *args, **kwargs):
super(botForm, self).__init__(*args, **kwargs)
self.fields['bot'] = forms.ChoiceField(choices=get_files(user))
This works fine and displays a list of all the users bots. The problem arises when I try to pass these values over to the 'game' page and access them here.
game\views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from game.models import game
from game.forms import GameForm
from upload.models import Document
from panel.forms import botForm
import league
def RPS(request):
if request.method == 'POST': # If the request is a POST method...
if 'PanelPlay' in request.POST:
panel = botForm(request.POST)
if panel.is_valid():
print panel.cleaned_data['bot']
elif 'GamePlay' in request.POST:
form = GameForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
leagueOuput = []
leagueOutput = league.run(form.cleaned_data['bot1'],form.cleaned_data['bot2'])
newGame = game()
newGame.bot1 = leagueOutput[0]
newGame.bot2 = leagueOutput[1]
newGame.bot1wins = leagueOutput[2]
newGame.bot2wins = leagueOutput[3]
newGame.save()
return HttpResponseRedirect(reverse('game.views.RPS')) # Redirect after POST
form = GameForm() # An unbound form
results = game.objects.all() # Load messages for the list page
return render_to_response('game.html', {'results': results, 'form': form}, context_instance=RequestContext(request))
When attempting to access and validate the panel data, I get the following error.
'QueryDict' object has no attribute 'id'
Referring to this specific line.
bots = Document.objects.filter(user=user.id)
I have found and read about a number of similar issues but I can't seem to carry over their solutions to my own project.
Thanks in advance for any and all help.
When you are constructing the botForm, you're passing request.POST (a QueryDict) as the user parameter. Did you mean
panel = botForm(request.user, data=request.POST)
?
(assuming you're using django authentification).

Categories