настраиваемые поля фляги-зефира

Я использую flask-marshmallow и mongoengine.

Также flask-restplus для моего сервера API.

Вот мой апи.py

class BoardSchema(ma.Schema):
    class Meta:
        fields = ('no', 'title', 'body', 'tags', 'created_at', 'views')

board_schema = BoardSchema()
boards_schema = BoardSchema(many=True)


class ArticleList(Resource):
    def get(self):
        articles = Board.objects.all()
        return boards_schema.jsonify(articles)

модель.py

from datetime import datetime
from mongoengine import *
from config import DB_NAME


connect(DB_NAME)


class Board(Document):
    d = datetime.now()
    date = "{}-{}-{}".format(d.year, d.month, d.day)

    no = SequenceField()
    title = StringField(required=True)
    body = StringField(required=True)
    tags = ListField(StringField())
    likes = ListField(StringField())
    views = ListField(StringField())
    password = StringField(required=True)
    created_at = DateTimeField(default=date)
    updated_at = DateTimeField(default=date)

Когда я обращаюсь к / article, это выглядит так ->

{
  "body": "123", 
  "created_at": "2018-08-20T00:00:00+00:00", 
  "no": 1, 
  "tags": [
    "MySQL", 
    "C"
  ], 
  "title": "\ud14c\uc2a4\ud2b8", 
  "views": [
    "127.0.0.1"
  ]
}

в "views" будет добавлен ip кто читал статью.

Но я хочу подсчитать весь список просмотров и включить его в свой результат.

Результат, который я хотел, здесь.

{
  "body": "123", 
  "created_at": "2018-08-20T00:00:00+00:00", 
  "no": 1, 
  "tags": [
    "MySQL", 
    "C"
  ], 
  "title": "\ud14c\uc2a4\ud2b8", 
  "views": 20
}

Я новичок в flask-marshmallow, поэтому я так запутался, как решить эту проблему.

Спасибо.


person Hide    schedule 20.08.2018    source источник
comment
Во-первых, просмотры по типу StringField? Было бы проще, если бы оно было целым.   -  person needtobe    schedule 20.08.2018
comment
Я не вижу вашей логики/конечной точки для просмотра одной статьи, но вы можете просто увеличивать количество просмотров следующим образом: single_article = Board.objects.first() single_article.views = single_article.views + 1   -  person needtobe    schedule 20.08.2018
comment
Возможно, это IntField, поэтому объявите views = IntField()   -  person needtobe    schedule 20.08.2018
comment
@needtobe views должен быть StringField внутри ListField. Потому что IP-адрес каждого зрителя будет храниться в полях просмотра. Таким образом, один ip может увеличить количество просмотров.   -  person Hide    schedule 20.08.2018
comment
@needtobe Итак, я хочу подсчитать все просмотры и представить их в своем результате.   -  person Hide    schedule 20.08.2018
comment
Ага, понятно. Затем вы можете изменить поле представлений прямо перед его сбросом с помощью настройки схемы.   -  person needtobe    schedule 20.08.2018


Ответы (3)


Может быть, вы можете попробовать так:

class BoardSchemaCustom(ma.ModelSchema):
    class Meta:
        model = Board

    views = ma.fields.method(deserialize="_custom_serializer")

    def _custom_serializer(self, obj):
        return len(obj.views)

Создайте экземпляр вашей пользовательской схемы:

custom_board_schema = BoardSchemaCustom()

и сбросить его:

dump, errors = custom_board_schema.schema.dump(Board.query.first())
>>> dump
person needtobe    schedule 20.08.2018
comment
Возможно, у фляги-зефира нет атрибута ModelSchema. Я запускаю после того, как напишу ваш код, он выдает AttributeError: 'Marshmallow' object has no attribute 'ModelSchema' ошибки в class BoardSchemaCuston(ma.ModelSchema): - person Hide; 21.08.2018
comment
Flask-marshmallow имеет атрибут ModelSchema, посмотрите здесь (flask-marshmallow.readthedocs.io/en/latest ) - person needtobe; 21.08.2018
comment
Попробуйте так: from flask_marshmallow import Marshmallow ma = Marshmallow(app), а затем ma.ModelSchema - person needtobe; 21.08.2018
comment
Мой код уже совпадает с вашим кодом. Но выдает ошибки. В документах этот пример использует sqlalchemy. Но моя БД - mongodb. Может быть, это были ошибки? - person Hide; 21.08.2018
comment
В этом примере не flask-marshmallow, а marshmallow-mongoengine. Чтобы ваш код работал, мне нужно установить marshmallow-mongoengine вместо flask-marshmallow. - person Hide; 21.08.2018
comment
Это было просто для целей презентации, flask_marshmallow также имеет поле ma.ModelSchema, но если оно не работает, вы можете попробовать использовать его marshmallow-mongoengine и установить его. - person needtobe; 21.08.2018

у меня такая же проблема. и мой код работает после установки marshmallow-sqlalchemy

pip install marshmallow-sqlalchemy

см. в официальной документации https://flask-marshmallow.readthedocs.io/en/latest/< /а>

person killer John    schedule 03.10.2019

Фрагмент ниже также будет работать:

class BoardSchemaCustom(ma.ModelSchema):
    class Meta:
        model = Board

    views = ma.fields.Function(lambda obj: len(obj.views))
person Emmanuel Robert Ssebaggala    schedule 24.09.2020