Mongoengine - erreur de sélection

Je fais une API qui utilise Mongoengine (MongoDB) et Flask.

J'ai un problème. J'ai une collection mongodb - schéma:

class Word(EmbeddedDocument):
    word_id = IntField()
    word = StringField()
    translation = StringField()
    strength = IntField()
    meta = {'collection': 'users'}

    def to_dict(self):
        return mongo_to_dict(self)

class User(Document):
    user_id = IntField()
    username = StringField()
    email = EmailField()
    password = StringField()
    words = ListField(EmbeddedDocumentField(Word))
    meta = {'collection': 'users',
    'ordering': ['-user_id']

je peux montrer le mot avec word_id avec url api/users/xxx/words / quand je supprime le mot avec l'ID 5, et la collection ressemblera à ceci

[
    {
        "username": "xxx",
        "password": "yyy",
        "words": [
            {
                "translation": "ajlkjbc", 
                "strength": 1, 
                "word": "abjlkc", 
                "word_id": 1
            }, 
            {
                "translation": "ajlkjbc", 
                "strength": 1, 
                "word": "ahkjc", 
                "word_id": 2
            }, 
            {
                "translation": "aklbc", 
                "strength": 5, 
                "word": "jklc", 
                "word_id": 3
            }, 
            {
                "translation": "afdfsc", 
                "strength": 1, 
                "word": "acjj", 
                "word_id": 4
            }, 
            {
                "translation": "dsadf", 
                "strength": 1, 
                "word": "dvdsf", 
                "word_id": 6
            }
        ]
    }
]

Le problème est quand je vais à url api/users/xxx/words/6 Ça ne marche pas.

Mon code pour cette URL est

@app.route('/api/users//words/', methods=['GET'])
def get_words(username):
     user = User.objects(username=username)
     l_user = user.to_json()
     decoded = json.loads(l_user)
     return Response(json.dumps(decoded[0]["words"][word_id-1], sort_keys=False, indent=4),
                mimetype='application/json')

Cela ne fonctionne pas si je supprime un mot au milieu.

0
Oui, c'est le problème. Je veux garder word_id identique. Donc, quand je veux supprimer le mot avec word_id 4, je veux garder word_id des autres parce que les mots sont synchronisés avec le client (Backbone collection). Donc quand je veux par exemple supprimer le mot avec url api/words/xxx/words/6, ce qui est déjà dans le client ça ne marchera pas car ce sera différent dans la base de données. Avec votre solution si j'avais 100 mots et je voudrais supprimer le mot avec word_id 50, je dois réécrire 50 mots, et puis je dois envoyer mes nouveaux mots au client encore et réécrire des modèles sur l
ajouté l'auteur SamuelMatis, source
Le word_id n'est-il pas encore 6? Vous devez vous en tenir compte ou maintenir un ordre strict dans la liste vous-même ... Je ne pense pas que vous puissiez mélanger les deux ...
ajouté l'auteur Asya Kamsky, source

1 Réponses

Une meilleure approche serait de filtrer l'élément correspondant par id ou de renvoyer un 404 s'il n'existe pas, par exemple:

@app.route('/api/users//words/', methods=['GET'])
def get_words(username):
     user = User.objects(username=username)
     word = [word for word user.words if word.word_id == word_id]
     if not word:
        return abort(404)
     return Response(word[0].to_json(sort_keys=False, indent=4),
                     mimetype='application/json')
0
ajouté