Django: interrogation de la vue en lecture seule sans clé primaire

class dbview(models.Model):
    # field definitions omitted for brevity
    class Meta:
        db_table = 'read_only_view'

def main(request):
    result = dbview.objects.all()

A attrapé une exception lors du rendu: (1054, "Colonne inconnue' read_only_view. id 'dans' Liste de champs'")

Il n'y a aucune clé primaire que je peux voir dans la vue. Est-il une solution?

Commentaire:
Je n'ai aucun contrôle sur la vue à laquelle j'accède avec Django. Le navigateur MySQL affiche des colonnes mais pas de clé primaire.

22
demandé sur dmi 2009-03-03 13:36:46

4 réponses

Quand vous dites ' Je n'ai aucun contrôle sur la vue à laquelle j'accède avec Django. Le navigateur MySQL affiche des colonnes mais pas de clé primaire.'

Je suppose que vous voulez dire qu'il s'agit d'une table héritée et que vous n'êtes pas autorisé à ajouter ou à modifier des colonnes?

Si c'est le cas et qu'il n'y a vraiment pas de clé primaire (même une chaîne ou une colonne non-int*), la table n'a pas été très bien configurée et les performances pourraient bien Puer.

Cela n'a pas d'importance pour vous cependant. Tout ce dont vous avez besoin est une colonne garantie pour être unique pour chaque ligne. Définissez-le sur ' primary_key = True dans votre modèle et Django sera heureux.

  • Il y a une autre possibilité qui serait problématique. S'il n'y a pas de colonne garantie unique, la table peut utiliser des clés primaires composites. C'est-à-dire qu'il spécifie que deux colonnes prises ensemble fourniront une clé primaire unique. C'est une modélisation relationnelle parfaitement valide mais malheureusement non supportée par Django. Dans ce cas vous ne pouvez pas faire grand chose en plus de SQL brut, sauf si vous pouvez obtenir une autre colonne ajoutée.
17
répondu Andy Baker 2009-03-04 10:50:30

J'ai ce problème tout le temps. J'ai une vue que je ne peux pas ou ne veux pas changer, mais je veux avoir une page pour afficher des informations composites (peut-être dans la section admin). Je remplace simplement la sauvegarde et soulève un NotImplementedError:

    def save(self, **kwargs):
        raise NotImplementedError()

(bien que ce ne soit probablement pas nécessaire dans la plupart des cas, mais cela me fait me sentir un peu mieux)

J'ai également défini managed sur False dans la classe Meta.

    class Meta:
       managed = False

Ensuite, je choisis juste n'importe quel champ et le marque comme clé primaire. Il n'a pas importe si c'est vraiment unique avec vous faites juste des filtres pour afficher des informations sur une page, etc.

Semble bien fonctionner pour moi. S "il vous plaît commment s" il y a des problèmes avec cette technique que je néglige.

13
répondu David S 2012-07-21 18:48:37

S'il est vraiment pas de clé primaire dans la vue, il n'y a pas de solution de contournement.

Django exige que chaque modèle à avoir exactement un champ primary_key=True.

3
répondu webjunkie 2009-03-03 11:51:13

Il aurait dû y avoir un champ id généré automatiquement lorsque vous avez exécuté syncdb (s'il n'y a pas de clé primaire définie dans votre modèle, Django insérera un AutoField pour vous).

Cette erreur signifie que Django demande à votre base de données le champ id, mais aucun n'existe. Pouvez-vous Exécuter django manage.py dbshell puis DESCRIBE read_only_view; et poster le résultat? Cela affichera toutes les colonnes qui se trouvent dans la base de données.

Sinon, pouvez-vous inclure la définition du modèle que vous avez exclue? (et confirmer que vous n'avez pas modifié la définition du modèle depuis que vous avez couru syncdb?)

1
répondu obeattie 2009-03-03 11:40:18