Почему JsonResponse не выполняет автоматическую сериализацию моей модели Django? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть эти модели:

class BaseModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True


class User(AbstractUser):
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(unique=True, null=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Post(BaseModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content_url = models.URLField(null=False)

Я хочу иметь возможность получить все модели из базы данных.Когда я делаю это:

urlpatterns = [
    path("", views.get_all_posts, name="get_all_posts")]

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.all()})

я получаю сообщение об ошибке сериализации JSON.Итак, согласно совету на других постах, я делаю это:

def get_all_posts(request):
    posts = serializers.serialize('json', Post.objects.all())
    return JsonResponse({"posts": json.loads(posts)})

Но затем я получаю объект этой формы:

('[{"model": "api.post", "pk": 1, "fields": {"created_at": '
 '"2019-05-06T20:22:43.928Z", "updated_at": "2019-05-06T20:22:43.928Z", '
 '"user": 1, "content_url": "tmp/posts/None.md"}}]')

Вы видите, насколько это смешно?Чтобы получить фактическое содержание сообщения, мне нужно сопоставить каждый «ответ» с его свойством fields, и даже тогда мне все еще не хватает первичного ключа !!

Мне интересно, почему JSONИнтерфейс ответа не так прост, как этот:

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.all()})

Кажется, что для доставки сериализованного JSON клиенту мне нужно перепрыгнуть через ряд обручей, которые, честно говоря, не должны существовать в производственной сетирамки.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 07 мая 2019

использовать format='python' в serialize() как:

def get_all_posts(request):
    posts = serializers.serialize(<b>'python',</b> Post.objects.all())
    return JsonResponse(<b>{"posts": posts}</b>)
0 голосов
/ 17 мая 2019

Используйте queryset values() / values_list() методы для сериализации:

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.values_list()})

он также поддерживает составные поля, поэтому не будет вложенной сериализации, которая подвержена ошибкам:

def get_all_posts(request):
    return JsonResponse({
        "posts": Post.objects.values('content_url', 'user__username')
    })

, но для некоторых сложных значений fleid он также может потерпеть неудачу.В таком случае конвертируйте сложные типы в простые типы Python в цикле понимания или используйте сторонний сериализатор, такой как DRF или tastypie.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...