Django物件.update_or_create [英] Django objects.update_or_create

查看:83
本文介绍了Django物件.update_or_create的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在芹菜上运行着一个periodic_task,用于查询最新的加密货币价格,但由于某种原因,每次要显示数据时,我都不会得到更新的记录,而我只是得到新的记录,而旧记录由于某种原因而保留./p>

tasks.py

  @periodic_task(run_every =(crontab(minute ='*/1')),name =更新密码率",ignore_result = True)def get_exchange_rate():api_url ="https://api.coinmarketcap.com/v1/ticker/"尝试:exchange_rates = requests.get(api_url).json()对于exchange_rates中的exchange_rate:CryptoPrices.objects.update_or_create(key = exchange_rate ['id'],symbol = exchange_rate ['symbol'],market_cap_usd = round(float(exchange_rate ['market_cap_usd']),3),volume_usd_24h = round(float(exchange_rate ['24h_volume_usd']),3),defaults = {'value':round(float(exchange_rate ['price_usd']),3)})logger.info(加密汇率已成功更新.")例外,例如e:打印(e) 

models.py

  class CryptoPrices(models.Model):键= models.CharField(max_length = 255)值= models.CharField(max_length = 255)符号= models.CharField(max_length = 255)volume_usd_24h = models.CharField(max_length = 255)market_cap_usd = models.CharField(max_length = 255) 

views.py

  def crypto_ticker(请求):list_prices = CryptoPrices.objects.get_queryset().order_by('pk')paginator = Paginator(list_prices,100)#显示每页100个价格页面= request.GET.get('page')价格= paginator.get_page(页)返回render(request,'crypto_ticker.html',{'price':price}) 

template.html:

  {%扩展了'base.html'%}{%load readmore%}{%阻止面包屑%}{{block.super}}»< a href ="{%url'post_list'%}">帖子</a>»< a href ="{%url'crypto_ticker'%}">加密货币代码</a>{%endblock%}{%封锁内容%}<!DOCTYPE html>< html>< head>< title>加密货币代码</title></head><身体>< h1 class ="center">加密行情记录</h1>< hr class ="hr-style">< div class ="center">< h4> {{价格}}在这里您可以找到所有常见问题< br>如果您仍然还有开放时间,请与< a href =#"> support</a>.</h4>联系.</div>< br>< div class ="paginator">< span>{%如果price.has_previous%}< a href =?page = 1">& laquo;第一< a>|</a</a>< a href =?page = {{price.previous_page_number}}">上一页</a>{% 万一 %}{%如果price.has_next%}< span>加密价格-{{price.paginator.num_pages}}页的{{price.number}}.</span>< a href =?page = {{price.next_page_number}}">下一步< a>|</a</a>< a href =?page = {{price.paginator.num_pages}}">最后& raquo;</a>{% 万一 %}</span></div>< table class ="table centercontentfloat class-three-box">< thead>< tr style ="font-size:small"><排名</th>< th>符号</th>< th>名称</th>< th>价格</th>< th>市值(USD)< th>第24小时.交易量(USD)/th</tr></thead>< tbody>{占价格%的价格的百分比}< tr style ="font-size:small">< td> {{price.id}}</td>< td> {{price.symbol}}</td>< td> {{price.key}}</td>< td> {{price.value}} $</td>< td style ="font-size:small"> {{price.market_cap_usd}} $</td>< td style ="font-size:small"> {{price.volume_usd_24h}} $</td></tr>{%endfor%}</tbody></table>< div class ="paginator">< span>{%如果price.has_previous%}< a href =?page = 1">& laquo;第一< a>|</a</a>< a href =?page = {{price.previous_page_number}}">上一页</a>{% 万一 %}{%如果price.has_next%}< span>加密价格-{{price.paginator.num_pages}}页的{{price.number}}.</span>< a href =?page = {{price.next_page_number}}">下一步< a>|</a</a>< a href =?page = {{price.paginator.num_pages}}">最后& raquo;</a>{% 万一 %}</span></div>{%endblock%} 

我从coinmarketcap api抓取的记录是否被保存/显示两次,是否有明显的原因?

如果我浏览页面,我会得到类似以下的内容:

加密货币价格-第1页,共21页.最后的 "排名符号名称价格市值(USD)24小时.交易量(美元)1 BTC比特币3795.6465 $ 66594617840.0 $ 8296474984.64 $2 ETH以太坊143.9996 $ 15106822040.0 $ 5043716023.22 $

并在第二页上:

«第一|上一页加密价格-第2页,共22页.最后的 "排名符号名称价格市值(USD)24小时.交易量(美元)101 BTC比特币3798.3016 $ 66641201438.0 $ 8304474934.43 $102 ETH以太坊144.0825 $ 15115524904.0 $ 5048205218.98 $

我不希望BTC也出现在第二页上,而只出现在第一页上吗?!?

如果我浏览所有页面,这些记录似乎没有更新,那么它们将在每次执行periodic_task后一次又一次地保存起来

亲切的问候

解决方案

您正在将查询中的所有字段用于现有实例.您只需要在此使用唯一的,其余在 defaults 字典中即可.

  CryptoPrices.objects.update_or_create(key = exchange_rate ['id'],symbol = exchange_rate ['symbol'],默认值= {"market_cap_usd":round(float(exchange_rate ['market_cap_usd']),3),"volume_usd_24h":round(float(exchange_rate ['24h_volume_usd']),3),值":round(float(exchange_rate ['price_usd']),3)}) 

i have a periodic_task running in celery that query for latest Cryptocurrency prices but for some reason, each time a want to display the data i dont get updated records i just get new ones and the old records are keep for some reason.

tasks.py

@periodic_task(run_every=(crontab(minute='*/1')), name="Update Crypto rate(s)", ignore_result=True)
def get_exchange_rate():
    api_url = "https://api.coinmarketcap.com/v1/ticker/"
    try:
        exchange_rates = requests.get(api_url).json()
        for exchange_rate in exchange_rates:
            CryptoPrices.objects.update_or_create(key=exchange_rate['id'],
                                                  symbol=exchange_rate['symbol'],
                                                  market_cap_usd=round(float(exchange_rate['market_cap_usd']), 3),
                                                  volume_usd_24h=round(float(exchange_rate['24h_volume_usd']), 3),
                                                  defaults={'value': round(float(exchange_rate['price_usd']), 3)}
                                                  )
        logger.info("Crypto exchange rate(s) updated successfully.")
    except Exception as e:
        print(e)

models.py

class CryptoPrices(models.Model):
    key = models.CharField(max_length=255)
    value = models.CharField(max_length=255)
    symbol = models.CharField(max_length=255)
    volume_usd_24h = models.CharField(max_length=255)
    market_cap_usd = models.CharField(max_length=255)

views.py

def crypto_ticker(request):
        list_prices = CryptoPrices.objects.get_queryset().order_by('pk')
        paginator = Paginator(list_prices, 100)  # Show 100 prices per page
        page = request.GET.get('page')
        price = paginator.get_page(page)
        return render(request, 'crypto_ticker.html', {'price': price})

template.html:

{% extends 'base.html' %}
{% load readmore %}

{% block breadcrumbs %}
    {{ block.super }} » <a href="{% url 'post_list' %}">Posts </a> »
    <a href="{% url 'crypto_ticker' %}">Crypto ticker</a>
{% endblock %}


{% block content %}

    <!DOCTYPE html>
    <html>
    <head>
        <title>Crypto ticker</title>
    </head>

    <body>
    <h1 class="center">Crypto ticker</h1>
    <hr class="hr-style">
    <div class="center">
        <h4>{{ prices }} Here you can find all frequently asked questions <br>
            if you still have still have any open points, please contact the <a href="#">support</a>.</h4>
    </div>
    <br>
    <div class="paginator">
        <span>
         {% if price.has_previous %}
            <a href="?page=1">&laquo; First <a> |</a></a>
            <a href="?page={{ price.previous_page_number }}">Previous</a>
        {% endif %}

        {% if price.has_next %}
            <span> Crypto prices - Page {{ price.number }} of {{ price.paginator.num_pages }}.</span>
            <a href="?page={{ price.next_page_number }}">Next<a> |</a></a>
            <a href="?page={{ price.paginator.num_pages }}">Last &raquo;</a>
        {% endif %}
       </span>
   </div>
    <table class="table centercontentfloat class-three-box">
        <thead>
            <tr style="font-size: small">
                <th>Ranking</th>
                <th>Symbol</th>
                <th>Name</th>
                <th>Price</th>
                <th>Market Cap (USD)</th>
                <th>24 hrs. Volume (USD)</th>
            </tr>
        </thead>
        <tbody>
        {% for price in price %}
            <tr style="font-size: small">
                <td>{{ price.id }}</td>
                <td>{{ price.symbol }}</td>
                <td>{{ price.key }}</td>
                <td>{{ price.value }} $</td>
                <td style="font-size: small">{{ price.market_cap_usd }} $</td>
                <td style="font-size: small">{{ price.volume_usd_24h }} $</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <div class="paginator">
        <span>
            {% if price.has_previous %}
            <a href="?page=1">&laquo; First <a> |</a></a>
            <a href="?page={{ price.previous_page_number }}">Previous</a>
        {% endif %}

        {% if price.has_next %}
            <span> Crypto prices - Page {{ price.number }} of {{ price.paginator.num_pages }}.</span>
            <a href="?page={{ price.next_page_number }}">Next<a> |</a></a>
            <a href="?page={{ price.paginator.num_pages }}">Last &raquo;</a>
        {% endif %}
       </span>
    </div>
{% endblock %}

Is there any notable reason why the records i grab from the coinmarketcap api is getting saved/ displayed twice?

if i go trough the pages i get back something like this:

Crypto prices - Page 1 of 21. Next | Last » Ranking Symbol Name Price Market Cap (USD) 24 hrs. Volume (USD) 1 BTC bitcoin 3795.6465 $ 66594617840.0 $ 8296474984.64 $ 2 ETH ethereum 143.9996 $ 15106822040.0 $ 5043716023.22 $

and on the second page:

« First | Previous Crypto prices - Page 2 of 22. Next | Last » Ranking Symbol Name Price Market Cap (USD) 24 hrs. Volume (USD) 101 BTC bitcoin 3798.3016 $ 66641201438.0 $ 8304474934.43 $ 102 ETH ethereum 144.0825 $ 15115524904.0 $ 5048205218.98 $

and i dont expect that BTC is also at the second page, only once at the first page?!?

It really seems if i go trough the pages, that the records dont get updated, they will get saved one after another after each periodic_task run

Kind regards

解决方案

You're using all the fields in the query for existing instances. You need to just use the unique ones there, and the rest in the defaults dict.

CryptoPrices.objects.update_or_create(
   key=exchange_rate['id'],
   symbol=exchange_rate['symbol'],
   defaults={             
       "market_cap_usd": round(float(exchange_rate['market_cap_usd']), 3),
       "volume_usd_24h": round(float(exchange_rate['24h_volume_usd']), 3),
       "value": round(float(exchange_rate['price_usd']), 3)
    })

这篇关于Django物件.update_or_create的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆