我正在尝试将 API 响应的数据保存在我的 Django 表中,但我面临的问题是 API 在一个包含多个词典的列表中进行响应,并且每次我调用 API 时词典的数量都会增加。
例子 第一次通话
A = [{foo:4,
bar:5}]
第二次通话
A = [{foo:4,
bar:5}, {foo:8, bar:10}]
第三次通话
A = [{foo:4,
bar:5}, {foo:8, bar:10}, {foo:12, bar:15}]
等等
我的模型是这样的:
class Tracking(models.Model):
foo = models.CharField(max_length=255, default=0)
bar = models.CharField(max_length=255, default=0)
我的观点.py
class trackapi(APIView):
def get(self, request, pk):
response = requests.request('GET', url, headers=headers, data=payload, auth=user_pass)
for i in response.text:
Tracking.objects.create(foo = i["foo"], bar = i["bar"]
但是这会在表中创建很多多个条目,我应该怎么做才能不复制表中的数据?
我尝试过的:
lr_id = LR.objects.filter(lr_quiz=pk)[0].id
invoice_id = Invoice.objects.filter(invoice_quiz=pk)[0].id
for i in track_response:
Tracking.objects.get_or_create(lr_no=lr_id,invoice_no=invoice_id,
tracking_id=i["_id"],trip_id = i["tripId"],telephone=i["tel"],
loc = i["loc"], address=i["address"],city=i["city"],
created_at=i["createdAt"])
API 数据:
[{"_id":"5dccedadff47e867a2833819","tel":"xxxxxxx","loc":[28.498692,77.095215],"tripId":"5dccedaaff47e867a28337ec","mode":"automated","osm_data":{"distance_remained":10791,"time_remained":1649.5},"distance_remained":10870,"time_remained":1173,"curr_ETA":"2019-11-14T06:43:19.664Z","address":"100,
The National Media Centre, Sector 24, Gurugram, Haryana 122022,
India","city":"Gurugram","createdAt":"2019-11-14T06:01:17.166Z"},{"_id":"5dccedacff47e867a2833801","tel":"xxxxxxx","loc":[28.498692,77.095215],"tripId":"5dccedaaff47e867a28337ec","mode":"automated","osm_data":{"distance_remained":10791,"time_remained":1649.5},"distance_remained":10870,"time_remained":1173,"curr_ETA":"2019-11-14T06:43:18.459Z","address":"100,
The National Media Centre, Sector 24, Gurugram, Haryana 122022,
India","city":"Gurugram","createdAt":"2019-11-14T06:01:16.163Z"}]
请您参考如下方法:
虽然@drd 的回答可能有效,但我认为可能有更好的方法来利用 Django 的广泛工具。
对于非常简单的字典,例如您示例中使用的 foo 和 bar 字典,很难使用以下方法,但我怀疑您的数据是否那么简单。
因此,您可以使用美妙的get_or_create 方法!来自docs :
A convenience method for looking up an object with the given kwargs (may be empty if your model has defaults for all fields), creating one if necessary.
Returns a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.
This is meant to prevent duplicate objects from being created when requests are made in parallel, and as a shortcut to boilerplatish code.
但是,为了确保它正常工作,因为这是一个边缘案例,你需要对它有一点技巧。
假设 API 返回的数据集类似于堆栈结构,您可以设计一个处理程序,根据每个条目在 API 返回的数据集中出现的位置为每个条目分配一个 ID,即第一个字典是 1,第二个是2,等等。
模型.py
class Tracking(models.Model):
id = models.CharField("ID", max_length=255, primary_key=True)
...
views.py
def get(...):
...
# we also need to deserialize the response data into an iterable list
data = json.loads(response.text)
for i, entry in enumerate(data):
Tracking.objects.get_or_create(pk=i, **entry)
这将在新对象出现时创建新对象,而不会因之前调用的重复内容而使您的数据库困惑。
编辑
如果从 API 获取的数据已经有某种唯一字段(在本例中为 _id),您可以只使用该值作为主键,如下所示:
views.py
def get(...):
...
for entry in data:
pk = entry.pop("_id")
Tracking.objects.get_or_create(pk=pk, **entry)
