Display crypto price in a table using django and cryptocompare - python

I'm trying to make a simple webpage in django where I can display the price of some cryptocurrencies. The user stores in the database the name of the crypto and its initial price. Then I want to fill a table with the ticker and the initial price taken from the database and the current price of each crypto taken with cryptocompare.
This is where the problem begin: the value of 'current price' is taken using cryptocompare, but how can I dinamycally display the value of the current price of each crypto in the table? Maybe the problem is easy to solve but I'm really new and I'm stuck, thanks in advance!
If you need more information ask me!
This is how the table in the index look like. I need to fill the last column with the daily price of the crypto
models.py
from django.db import models
# Create your models here.
class crypto(models.Model):
ticker = models.CharField(max_length=200)
initial_price = models.FloatField()
def __str__(self):
return self.ticker
views.py
from .models import crypto
def index_view(request):
chart = FuncAnimation(plt.gcf(), animate, interval=1000)
ticker_list = crypto.objects.all()
return render(request, 'cryptochart/index.html', {'chart': chart, 'ticker_list': ticker_list})
and last, in a file called utils.py I wrote the functions to get the price
import cryptocompare
#get price of cryptocurrency
def get_crypto_price(cryptocurrency,currency):
return cryptocompare.get_price(cryptocurrency,currency=currency)[cryptocurrency][currency]
#get fullname of the cryptocurrency
def get_crypto_name(cryptocurrency):
return cryptocompare.get_coin_list()[cryptocurrency]['FullName']
index.html
<table style="width: 100%;">
<tr>
<th>Ticker</th>
<th>Prezzo Iniziale</th>
<th>Prezzo Giornaliero</th>
</tr>
{% if ticker_list %}
{% for ticker in ticker_list%}
<tr>
<td>{{ticker.ticker}}</td>
<td>{{ticker.initial_price}}</td>
<td>{{???}}</td>
</tr>
{%endfor%}
{% endif %}
</table>

Related

django Insert or Update record

the insert works but multiple data enters, when two data are inserted when I try to update, it does not update the record
I just want that when the data is already have record in the database, just update. if not, it will insert
def GroupOfProduct(request):
global productOrderList
relatedid_id = request.POST.get("relatedid")
groups = ProductRelatedGroup(id=id)
productOrderList=[]
try:
for products_id in request.POST.getlist("product"):
products = Product(id=products_id)
insert_update_groupofproduct = ProductRelatedGroupAndProduct(
product = products
)
insert_update_groupofproduct.save()
except ProductRelatedGroupAndProduct.DoesNotExist:
for products_id in request.GET.getlist("relatedid"):
products = Product(id=products_id)
insert_update_groupofproduct = ProductRelatedGroupAndProduct.objects.get(id=products)
insert_update_groupofproduct.product = products
insert_update_groupofproduct.save()
return redirect(relatedgroup)
this is my models.py
class Product(models.Model):
product = models.CharField(max_length=500)
class ProductRelatedGroup(models.Model):
category = models.CharField(max_length=500, blank=True)
class ProductRelatedGroupAndProduct(models.Model):
productrelatedgroup = models.ForeignKey(ProductRelatedGroup,on_delete=models.SET_NULL, null=True, blank=True,verbose_name="Product Related Group")
product = models.ForeignKey(Product,on_delete=models.SET_NULL, null=True, blank=True,verbose_name="Product")
UPDATE
I tried this, the insert works fine, but the update does not work
def GroupOfProduct(request):
global productOrderList
groups = ProductRelatedGroup(id=id)
idproduct = request.POST.get('relatedid')
if ProductRelatedGroupAndProduct.objects.filter(id=idproduct).exists():
print("update")
for products_id in request.GET.getlist("relatedid"):
products = Product(id=products_id)
insert_update_groupofproduct = ProductRelatedGroupAndProduct.objects.get(id=products)
insert_update_groupofproduct.product = products
insert_update_groupofproduct.save()
return redirect(relatedgroup)
else:
productOrderList = []
for isa in request.POST.getlist('relatedid'):
productOrderList.append(isa)
i = 0
for i in productOrderList:
for products_id in request.POST.getlist("product"):
products = Product(id=products_id)
insert_update_groupofproduct = ProductRelatedGroupAndProduct(
productrelatedgroup=groups,
product=products
)
insert_update_groupofproduct.save()
return redirect(relatedgroup)
return redirect(relatedgroup)
FLOW OF MY PROGRAM (with picture)
when the admin-user Insert data just (like this)
the batch insert work perfectly fine
and when i tried to update (batch update)
only one data updated
and when i tried to insert again (just like this)
no result
In Insert
<QueryDict: {'csrfmiddlewaretoken': ['F3evgRJwNw4p5XCOVE0qeFhP3gmGG5ay4GBbpoZQg3P5l6TNXHY7KN2lD56s6NCU'], 'relatedid': ['200', '201']}>
This is my html,
{% for relatedgroups in relatedgroups %}
<input type="hidden" name="relatedid" value="{{relatedgroups.id}}">
{% endfor %}
<fieldset class="module aligned ">
<div class="form-row field-user_permissions">
<div>
<div class="related-widget-wrapper">
<select name="product" id="id_user_permissions" multiple class="selectfilter" data-field-name="Product" data-is-stacked="0">
{% for relatedgroups in relatedgroups %}
<option value="{{relatedgroups.product.id}}" selected>{{relatedgroups.product}}</option>
{% endfor %}
{% for product in products %}
<option value="{{product.id}}">{{product.id}}-{{product}}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</fieldset>
when the data is selected or already have data in the database it will shows in Chosen Product box
Please use update_or_create method. This method if a data is exist then updated the details else newly inserted.
Reference:
https://www.kite.com/python/docs/django.db.models.QuerySet.update_or_create
https://djangosnippets.org/snippets/1114/
def GroupOfProduct(request):
group_id = request.POST.get('group')
groups = ProductRelatedGroup(id=group_id)
idproduct = request.POST.get('product')
for products_id in request.POST.getlist("product"):
products = Product(id=products_id)
ProductRelatedGroupAndProduct.objects.update_or_create(id=idproduct,defaults={'product':products,'productrelatedgroup':groups})
return redirect(relatedgroup)
We need to delete all the records first from ProductRelatedGroupAndProduct using the related_ids (product ids which were already selected) and then enter again into ProductRelatedGroupAndProduct using product_ids (product ids which are selected).
Why we need to delete ?
In a situation where you want to remove a product from the selected list, an update would not delete the relation. In-order to remove that product from the selected list we need to delete that relation (not the Product).
def GroupOfProduct(request):
related_ids = request.POST.getlist('relatedid')
product_ids = request.POST.getlist("product")
# delete the existing ProductRelatedGroupAndProduct entries
for product_id in related_ids:
product = Product.objects.filter(id=product_id).first()
obj = ProductRelatedGroupAndProduct.objects.get(product = product)
obj.delete()
# create new records in ProductRelatedGroupAndProduct with the selected product_ids
for product_id in product_ids:
product = Product.objects.filter(id=product_id).first()
obj = ProductRelatedGroupAndProduct(
product = product,
)
obj.save()

Python/ Django- add a custom column to tables generated by a view

I have a page on my Django website, which is displaying a number of tables based on information stored in the database.
The view being used to create the page displaying the tables is defined with:
def current_budget(request, budget_id):
""" View the active provisional/deposit budget """
budget = Budget.objects.select_related('project', 'project__budget_overview').prefetch_related('project__projectroom_set', 'project__budget_versions', 'budget_items').get(id=budget_id)
project = budget.project
# project.projectroom_set.filter(budgetitem__isnull=True, cciitem__isnull=True).delete()
if project.budget_overview.deposit_budget_saved: return HttpResponseRedirect(reverse('costing:combined_budget', args=[project.id]))
#This is now done in the costing_home view
# if not budget:
# Budget.objects.create(project=project, current_marker=1)
if not budget.budget_items.exists() and not project.budget_overview.deposit_budget_saved: init_budget(budget) # Create initial BudgetItem objects as standard
budget_items = budget.budget_items.select_related('budget', 'budget__project', 'project_room', 'project_room__room', 'room')#.order_by('build_type', 'build_type_detail', 'project_room', 'order') # .exclude(build_type=None)
budget_items2 = None #budget.budget_items.filter(build_type=None).order_by('build_type_detail', 'project_room', 'room')
context = {
'project': project,
'budget': budget,
'offset1': -5,
'offset2': -4,
}
try: context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs
except ObjectDoesNotExist: pass
if request.GET.get('version') or project.budget_overview.deposit_budget_saved: #Make the fields all readonly
context['readonly'] = True
context['offset1'] = -7
if request.GET.get('report'): #Schedule of works report uses same data as current budget form
""" Client view of budget. IMPORTANT: Hidden items are not displayed here """
items_grouped = groupby(budget_items.filter(hidden_cost=False), lambda x: x.build_type)
grouped_items = [(x, list(y)) for x, y in items_grouped]
context['grouped_items'] = grouped_items
if request.GET.get('pdf'):
template = get_template('costing/report_schedule_of_works.html')
html = template.render(context)
file = open('test.pdf', "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), link_callback=fetch_resources, dest=file,
encoding='utf-8')
file.seek(0)
pdf = file.read()
file.close()
return HttpResponse(pdf, 'application/pdf')
else:
context['webview'] = 1
context['html'] = render_to_string('costing/report_schedule_of_works.html', context)
context['active_tab'] = '3'
return render(request, 'costing/reports_pre_deposit.html', context)
else:
if not context.get('readonly'):
context['skill_day_rate'] = skill_day_rate
context['labour_day_rate'] = labour_day_rate
# Dict with ProjectRoom ids and the total for the room
room_totals = {}
for project_room in project.projectroom_set.all():
room_totals[project_room.id] = sum(item.total_inc_profit for item in budget_items if item.project_room == project_room)
context['room_totals'] = room_totals
item_formset = BudgetItemFormset(queryset=budget_items, form_kwargs={'project': project})
item_form = item_formset.forms[0]
context['field_count'] = len(item_form.visible_fields())
context['ao_field_count'] = len(item_form.visible_fields())
room_choices = project.room_choices
context['formset'] = item_formset
context['widths'] = budget_item_column_widths #First column is add/delete options to allow for forloop count offset
context['options_width'] = options_width #First column is add/delete options to allow for forloop count offset
context['labour_rate'] = labour_day_rate
context['skill_rate'] = skill_day_rate
context['item_code_options'] = ItemCodeForm()
skill_total = int(budget_items.aggregate(Sum('skill_days'))['skill_days__sum'] or 0)
if budget_items2: labour_total = int(budget_items2.aggregate(Sum('labour_days'))['labour_days__sum'])
else: labour_total = 0
return render(request, 'costing/budget_current.html', context)
I now want to add a 'custom' column to these tables, to allow the user to enter their own notes in (i.e. one that will not be displaying data retrieved from the database, but which should add information to each row in the database when it is saved).
How would I do this? I would have thought that I will do it in the view (Python), rather than in the template (HTML), since the view is where the tables are being constructed?
Edit
So, I've added the extra field to the model in models.py for the app:
class Deposit(models.Model):
""" Each Deposit is linked to a Payment, whose is_booking_deposit field = True """
project = models.OneToOneField('projects.Project', null=True, blank=True)
half_paid = models.DateField(null=True, blank=True)
date_received = models.DateField(null=True, blank=True)
amount_exc_vat = models.DecimalField(decimal_places=2, max_digits=12, null=True, blank=True)
invoice_raised = models.DateField(null=True, blank=True)
notes = models.TextField(null=True, blank=True)
# Create a column for 'custom notes' in the tables:
custom_notes = models.TextField(null=True, blank=True) #Add the column to table in tables.py
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
payment = models.OneToOneField(Payment, null=True)
...
The field that I've added to the Deposit model above is the custom_notes one.
I also tried adding the same field to the BudgetItemTable() in tables.py:
class BudgetItemTable(tables.Table):
# Add a column for 'custom notes' to the tables for current budget
custom_notes = tables.Column(accessor='self.custom_notes')
class Meta:
model = BudgetItem
attrs = {"class": "paleblue"}
exclude = ('id')
I've run python manage.py makemigrations & python manage.py migrate myApp, but when I refresh my browser to view this page again, the new column for my table is not displayed- do I need to add it to the view somehow? How would I do this?
Edit
The HTML file for the view that displays the table I want to add a column to has the following structure:
...
{% block page_options_style %}allow-footer{% endblock page_options_style %}
{% block page_options %}
...
{% block report %}
<div id='budget_form' class="col-12" data-pr="{{project.id}}" style="margin-bottom:7em;">
<form class="autosave_form formset num_refresh text-sm" data-view-url="{% url 'costing:save_items' budget.id %}">{% csrf_token %}
{{formset.management_form}}
<div>
<table ...>
<thead class=... >
<tr class=...>
...
<!-- code to get table headings here -->
<th style="width:{{options_width}}">Custom Notes</th>
<!-- I added the 'Custom Notes' heading myself -->
</tr>
</thead>
...
<tbody>
...
<tr id="item_{{forloop.counter}}" class="{% cycle 'odd' 'even' %}">
...
<!-- code add columns and populate rows here -->
<td>
<a class="delete" ... ></a>
<!-- I can see this column with the 'delete' values is the last column in the table on the webpage, so I want to manually add another column after it in the table- I tried doing this by adding the following tags: -->
</td>
<td>
<a class="custom_notes" type="text" value=""></a>
</td>
...
</tr>
</tr>
</tbody>
</table>
...
</tbody>
</table>
</div>
</form>
I tried to add the 'Custom Notes' column to the table with the lines:
<td>
<a class="custom_notes" type="text" value=""></a>
</td>
When I view this page in the browser, I can see the Custom Notes column heading that I've added, displayed above the table, but it is displayed just to the right of where the table ends (I expected the column that I added to the table to be displayed below it).
The table column for 'custom notes' that I have tried adding is not displayed in the table at all...
Why is this? How can I get the new column to be displayed in the table on the webpage? I've added the corresponding field to the model in models.py, so although there won't be any data in this field for any of the items in the database at the moment, when the user enters data in this field in the table, there is somewhere for those values to be stored in the model in the database...
Edit
I managed to add this additional field to the table by appending the following HTML to the table, just inside the last two </tr> tags, inside </tbody></table>:
<td>
<a class="custom_notes" type="text" value=""></a>
<input id="budget_notes" type="text" width="100" value="">
</td>
But for some reason, the text input field that I have added is very narrow- you can't see more than a few characters of text at a time when typing into it. I tried specifying the width of the field using width="100", as shown above, but this doesn't appear to have made any difference. How can I force the cells in this column to have a set width?

Django- Using Parameters To Display Entry

My database is setup something like.
class comments(models.Model):
min = models.FloatField()
max = models.FloatField()
comment = models.CharField(max_length=255)
In my view, I grab a float value from the user. I want to take that value use the Min/Max as parameters and if that float value is between the Min/Max, display the comment that's associated to it. At times there might be more then 1 match, however for now I cant even figure out how to do the first step.
Use the filter() method of a model manager with a combination of __lte/__gte lookups:
def comments(request):
value = float(request.GET['value'])
return render(request, 'comments.html',
{'comments': comments.objects.filter(min__lte=value,
max__gte=value)})
And then in the comments.html:
{% for comment in comments %}
<div>{{ comment.comment }}</div>
{% endfor %}

2 different search in a view

I have two tables one that stores information from a medical record and the other a second medical consultation, what I want is to make a search and if the patient had a second medical consultation shows me the information of the second medical consultation in my template, if the patient doesn't have a second medical consultation only show me the information of the medical record.
I need help and ideas on how I can do it, I'm new with Django and Python , I do the search in a view in the following way, the problem with this search is that I only see the medical record and I need that if the patient had second medical consultation to display the information.
View.py
def Expediente_Detalle(request, credencial):
Expediente_Detalle = get_object_or_404(ExpedienteConsultaInicial, credencial_consultainicial=credencial)
return render(request, 'ExpedienteDetalle.html', {'Expediente_Detalle': Expediente_Detalle})
Models.py
class ExpedienteConsultaInicial(models.Model):
credencial_consultainicial = models.CharField(max_length=10, null=True, blank=True)
def __unicode__(self):
return self.credencial_consultainicial
class ConsultasSubsecuentes(models.Model):
Consultasbc_credencial =models.ForeignKey(ExpedienteConsultaInicial,
related_name='csb_credencial')
Try:
#Models
class ExpedienteConsultaInicial(models.Model):
#max_legth=10 might be too small
credencial_consultainicial = models.CharField(max_length=100, null=True, blank=True)
def __unicode__(self):
return self.credencial_consultainicial
class ConsultasSubsecuentes(models.Model):
#related_name is name of attribute of instance of model
#to (not from!) which ForeignKey points.
#Like:
#assuming that `related_name` is 'consultations'
#instance = ExpedienteConsultaInicial.objects.get(
# credencial_consultainicial='text text text'
#)
#instaqnce.consultations.all()
#So I suggest to change `related_name` to something that will explain what data of this model means in context of model to which it points with foreign key.
consultasbc_credencial = models.ForeignKey(ExpedienteConsultaInicial,
related_name='consultations')
#View
def expediente_detalle(request, credencial):
#Another suggestion is to not abuse CamelCase - look for PEP8
#It is Python's code-style guide.
detalle = get_object_or_404(ExpedienteConsultaInicial, credencial_consultainicial=credencial)
subsequent_consultations = detalle.csb_credencial.all()
return render(request, 'ExpedienteDetalle.html', {'Expediente_Detalle': detalle, 'consultations': subsequent_consultations})
Useful links:
Following relationships backward - thats why I suggest you to
change related_name
PEP8 - and this is about CamelCase and
Python's code-style.
All you need to do is to execute another query, and provide the result to your template
def Expediente_Detalle(request, credencial):
Expediente_Detalle = get_object_or_404(ExpedienteConsultaInicial, credencial_consultainicial=credencial)
second_consultation = ExpedienteConsultaInicial.objects.filter(..)
return render(request, 'ExpedienteDetalle.html', {'Expediente_Detalle': Expediente_Detalle, 'second_consultation': second_consultation})
Then, in your template, iterate over second_consultation:
{% for c in second_consultation %}
<p> {{ c.credencial_consultainicial }} </p>
{% endfor %}

Django - Rating System View & Template

I have a content that I'd like to rate on multiple criteria.
Imagine this kind of model:
class Content(models.Model):
name = models.CharField(max_length=50)
class Criterion(models.Model):
name = models.CharField(max_length=50)
content = models.ForeignKey(Content)
class ContRate(models.Model):
user = models.ForeignKey(User, help_text="Who rated ?")
crit = models.ForeignKey(Criterion)
rate = models.DecimalField()
The user has a page displaying the content.
From this page, he can also rate the content on the criteria set
The rating will be done with Ajax.
Now I'm trying to implement the view & the template
view.py
#...
def viewcont(request, content_id):
"""The user can view a content & rate it"""
content = get_object_or_404(Content, pk=content_id)
RateFormSet = modelformset_factory(ContRate)
formset = RateFormSet(queryset=ContRate.objects.filter(content=content, user=request.user))
objs = {
'content': content,
'forms': formset,
}
return render_to_response('content/content_detail.html', objs
, context_instance=RequestContext(request)
)
#...
content_detail.html
<!-- ... -->
<div id="rating">
<ul>
{% for crit in content.crit_set.all %}
<li>
{{ crit }}
<div class="rateit"
data-rateit-value="the_actual_rating_if_already_there"
data-rateit-ispreset="true"
crit-id="{{ crit.id }}"></div>
</li>
{% endfor %}
</ul>
</div>
<!-- ... -->
Now how can I use the forms formset to display the actual rates ?
And how can I draw an empty form to be posted by Ajax from any clicked star ?
(I know the javascript/jQuery part)
Not sure what the point of the formset is here. The rates are all available via the criteria object, using the reverse foreign key to ContRate in exactly the same way as you've done from Criteria to Content.
To make this as efficient as possible, you probably want to get the relevant ratings in the view and bring them together into a single datastructure:
content = get_object_or_404(Content, pk=content_id)
criteria = content.criteria_set.all()
user_ratings = ContRate.objects.filter(content=content, user=request.user)
ratings_dict = dict((c.crit_id, c.rate) for c in user_ratings)
for crit in criteria:
crit.user_rating = ratings_dict.get(crit.id)
Now you can pass criteria directly to your template, and there you can iterate through it to show the user_rating for each one.
(Final point: "criteria" is plural, the singular is "criterion". :-)

Categories

Resources