I hope this makes sense... I am building a crypto asset list page (easy); however, in the {% for %} loop I would like to include a variable inside a variable. Showing the code will make more sense:
Tempalte.html
{% for crypto_asset in objects__list_cryptoAssets %}
<tr role="row" >
<td role="cell">{{ api_external_prices.bitcoin.usd }}</td>
</tr>
{% endfor %}
So the {% for %} loop grabs all the crypto assets and then I can use Django template {{ asset_class.slug }} to grab all slugs... nothing exceptional here. This variable {{ api_external_prices.bitcoin.usd }} grabs external USD prices for Bitcoin, {{ api_external_prices.bitcoin.eur }} prices in EUR, and so forth... nothing exceptional here either.
Here is where the question comes :: the idea would be to have something like {{ api_external_prices.{{ asset_class.slug }}.usd }}... so each crypto would have its own price FX fetched correctly. Is it possible to have a variable inside a variable?
CodePudding user response:
They are several ways you can implement this:
Template filters
You can create a template filter api_external_prices
that takes asset_class
and the crypto type as parameters and returns the value.
The syntax would be something link this, where api_external_prices
is the name of the template filter:
{{ asset_class|api_external_prices:"usd" }}
See here for more info about this feature: https://docs.djangoproject.com/en/4.0/howto/custom-template-tags/#writing-custom-template-filters
Methods
Another approach would be to have api_external_prices
as method on your asset_class
object, which returns an object that has a usd
property. api_external_prices
here can just be a wrapper that calls a central module/function, but this would make it much easier to use it in templates.
{{ asset_class.api_external_prices.usd }}
The first approach is similar to what you are asking, but personally I would prefer to use the 2nd approach, because it saves you from introducing as template filter.
CodePudding user response:
I hope this helps on how you could implement Method 2 from your above answer.
Views.py
@login_required(login_url='xxx', redirect_field_name = '')
@require_http_methods(["GET", "POST"])
def view_cryptoAsset_list(request, *args, **kwargs):
template_name = 'xxx'
if request.user.is_authenticated and request.user.allow_private_access and request.user.is_superuser:
if request.method == 'GET':
context = {}
objects__list_cryptoAssets = CryptoAsset.objects.all()
objects__list_foreignExchange = ForeignExchange.objects.all()
context = get_crypto_asset_list(objects__list_cryptoAssets, context)
context = get_real_time_prices(objects__list_cryptoAssets, objects__list_foreignExchange, context)
return render(request, template_name, context)
else:
return HttpResponseRedirect(reverse('page__error_404'))
else:
return HttpResponseRedirect(reverse('page__home'))
Utils.py
def get_crypto_asset_list(objects__list_cryptoAssets, context):
if objects__list_cryptoAssets.count() > 0:
extra_context = { 'xxx': xxx,
'xxx': xxx,
'xxx': xxx,
'xxx': xxx}
else:
extra_context = { 'xxx': xxx,
'xxx': xxx,
'xxx': xxx}
context.update(extra_context)
return context
def get_real_time_prices(objects__list_cryptoAssets, objects__list_foreignExchange, context):
raw_crypto = objects__list_cryptoAssets.values('slug_name')
dict_crypto = []
for value in raw_crypto.values():
raw_slugs = value.get('slug_name')
dict_crypto.append(raw_slugs)
stringCrypto = ",".join(dict_crypto)
raw_foreign_exchange = objects__list_foreignExchange.values('slug')
dict_fx = []
for value in raw_foreign_exchange.values():
raw_slugs = value.get('slug')
dict_fx.append(raw_slugs)
stringFX = ",".join(dict_fx)
url = "xxx"
response = urllib.request.urlopen(url)
api_external_prices = json.loads(response.read())
extra_context = {'api_external_prices': api_external_prices}
context.update(extra_context)
return context