Я хочу создать json-файл из моей базы данных Django sqlite3 в качестве резервной копии, а не отображать его на веб-странице.
Я могу получить данные из базы данных sqlite3 и спроецировать их на веб-страницу в формате Json, но у меня возникают проблемы с воспроизведением этого, когда я хочу создать файл. Я новичок в python, Django и работе с базами данных. Я просмотрел и попробовал несколько частей кода, но вся информация, которую я смог найти, относилась к тому, чего я уже достиг, то есть к отображению данных на веб-странице.
Вот как я сейчас использую свой файл views.py для отображения данных на веб-странице.
import json
from django.utils import timezone
from django.db.models import Q
from django.http import JsonResponse
from django.views import View
from chpapi.models import BlockedList
class IPListJsonView(View):
def get(self, request):
json_response = {
"version": "",
"description": "",
"objects": [
{
"name": "",
"id": "",
"description": "",
"ranges": ["2.2.2.2"],
},
],
}
group_map = {}
for ip in BlockedList.objects.filter(
Q(end_date__isnull=True) | Q(end_date__gte=timezone.now())
).select_related("group"):
group_id = str(ip.group.id)
if group_id not in group_map:
group_map[group_id] = {
"name": ip.group.name,
"id": ip.group.group_id,
"description": ip.group.description,
"ranges": [],
}
group_map[group_id]["ranges"].append(ip.address)
json_response["objects"] = list(group_map.values())
return JsonResponse(json_response)
Приведенный выше код выдает то, что я хочу, мне приходится опускать некоторые объекты, но в основном четыре столбца, которые я беру из models.py - это название, group_id, описание и ranges - значение IP, которое имеет свое собственное определение, поскольку Django GenericIPAddress не поддерживает некоторые атрибуты, которые я хочу.
Я подумал, что простое исправление с точки зрения генерации файла также (Это в целях безопасности; в случае, если база данных или резервная копия может быть повреждена) было бы просто вставить этот код ниже.
data = JsonResponse
with open('test_data.json', 'w') as fp:
json.dump(data, fp, indent=4)
В итоге получается, что файл создается, но он пустой, и я думаю, что мне придется написать новый класс в представлениях для записи файла. Если возможно, если у кого-то есть статьи или даже решения по извлечению колонок из базы данных Sqlite3 и записи их в файл в формате json, это было бы полезно. Или если возможно включить создание файла в тот же класс views.
Пожалуйста, дайте мне знать, если я не включил достаточно информации, и я отредактирую и улучшу это сообщение.
Вам нужен сериализатор, который преобразует ваши данные в json. Затем вы можете использовать его как в обычном представлении, так и для создания файла.
with open("test_data.json", "w") as out:
my_json_serializer.serialize(BlockedList.objects.filter(...), stream=out)
Дополнительная информация здесь:
https://docs.djangoproject.com/en/5.0/topics/serialization/#serializing-data
У вас уже есть данные в формате JSON в json_response
, так что все, что осталось сделать, это записать эти данные в файл. Поскольку вы не можете полностью положиться на корректность рабочей директории вашего сервера, я бы рекомендовал явно указать директорию для этих дампов в настройках и использовать ее.
from django.conf import settings
import json
import time
# ...
dump_path = os.path.join(settings.DUMPS_DIRECTORY, f"dump-{int(time.time())}.json")
with open(dump_path, "w") as fp:
json.dump(json_response, fp)
return JsonResponse({"message": f"ok, saved {dump_path}"})
С другой стороны, если вы хотите передать данные пользователю, но указать браузеру пользователя, что он должен обрабатывать их как файл, используйте Content-Disposition
заголовок, чтобы сказать об этом:
filename = f"dump-{int(time.time())}.json"
response = JsonResponse(json_response)
response["Content-Disposition"] = f"attachment; filename={filename}"
return response