2010-02-25 4 views
5

J'ai un problème unique de la façon dont il devrait être géré dans admin django.Meilleure façon de représenter plusieurs à plusieurs relation dans admin django

Je suit la structure des modèles ...

class Product(models.Model): 
    name = models.CharField(max_length = 100) 
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2) 


    def __unicode__(self): 
     return self.name 


class Country(models.Model): 
    name = models.CharField(max_length = 2) 
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)  

    def __unicode__(self): 
     return self.name 


class CountryProduct(models.Model): 
    country = models.ForeignKey(Country) 
    product = models.ForeignKey(Product) 
    overriden_price = models.DecimalField(max_digits = 5, decimal_places = 2) 

    class Meta: 
     unique_together = (("country", "product"),) 

Comme le montre ici, il y a beaucoup à plusieurs entre produits et pays .... Je veux fournir une interface d'administration pour le prix de base prioritaire pour le pays donné et produit.

Une option pour avoir ui comme suit, ici le tiret (-) représente le prix par défaut et la valeur en nombre représente le prix de remplacement pour le pays et le produit donnés.

countries -> | US | UK 
products  |  | 
--------------------------- 
Product1  | - | 10 
Product2  | 5 | 7 

Mais je ne sais pas comment faire ....

Je suis ouvert à examiner d'autres approches (y compris les changements dans la structure du modèle), ainsi que tant qu'il répond à l'exigence. .. Votre entrée de toute sorte sera certainement utile pour moi ...

Merci à l'avance :)

Répondre

2

I GOT la solution, voici ma réponse à ma question ... Permettez-moi de partager avec vous ... J'ai changé le modèle manière suivante ....

class Product(models.Model): 
    name = models.CharField(max_length = 100) 
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2) 


    def __unicode__(self): 
     return self.name 


class Country(models.Model): 
    name = models.CharField(max_length = 2) 
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)  
    products = models.ManyToManyField(Product, through = 'CountryProduct') 

    def __unicode__(self): 
     return self.name 


class CountryProduct(models.Model): 
    country = models.ForeignKey(Country) 
    product = models.ForeignKey(Product) 
    overriden_price = models.DecimalField(max_digits = 5, decimal_places = 2) 

    class Meta: 
     unique_together = (("country", "product"),) 


class CountryProductInline(admin.TabularInline): 
    model = CountryProduct 

class CountryAdmin(admin.ModelAdmin): 
    inlines = [CountryProductInline] 

class ProductAdmin(admin.ModelAdmin): 
    inlines = [CountryProductInline] 

Bien ce n'est pas la façon dont je m'attendais, cela me donne encore meilleure solution ....

0

Il n'y a pas moyen intégré à l'administrateur de django pour faire ce que vous avez besoin.

Vous pouvez créer votre propre vue personnalisée, et le faire de cette façon. Vous pouvez ajouter des vues supplémentaires à une classe admin.ModelAdmin, qui fera ce dont vous avez besoin.

0

Ceci est - potentiellement - une conception terrible. Votre table de base de données doit contenir le prix correct.

Votre application doit maintenant faire deux choses. Il doit obtenir un prix par défaut ailleurs (pas dans ce tableau) et il doit également obtenir un prix de remplacement (à partir de cette table) et mettre les deux informations ensemble.

Vous ne pouvez pas rendre trivialement le travail SQL avec le type de grille que vous montrez.

Vous ne pouvez pas facilement faire fonctionner l'administrateur Django avec une grille comme vous le montrez. Vous pouvez essayer de créer un modèle de grille, mais il est unique à cette relation plusieurs-à-plusieurs. Vous devez également personnaliser les vues d'administration Django pour utiliser votre modèle pour une table plusieurs-à-plusieurs et utiliser le modèle par défaut ordinaire. pour toutes les autres tables. Pour créer la grille, vous devez aller chercher tous vos pays et produits. Vous devez ensuite créer la liste de listes appropriée. Vous pouvez ensuite écrire votre propre modèle pour l'afficher. Après avoir plus de 12 pays, la grille sera tellement large qu'elle sera presque inutile. Mais pour les premiers pays, vous pouvez faire ce travail.

Pour cela, vous devrez créer votre propre modèle et votre propre fonction de visualisation.

Modifier

« Je suis ouvert à examiner d'autres approches (y compris les changements dans la structure du modèle), ainsi que tant qu'il répond à l'exigence de »

Quelle exigence? La mauvaise conception où il faut deux requêtes pour trouver le prix? Est-ce nécessaire?

Ou la disposition de grille très difficile? Est-ce nécessaire?Il n'est pas clair ce que "l'exigence" est, il n'est donc pas possible de proposer une alternative. Il est seulement possible de dire

  1. Une conception SQL qui interroge la base et remplace séparément sera plus lente et plus complexe.

  2. Un design SQL qui a une seule valeur qui est chargé à partir d'un "défaut dynamique" et qui peut être modifié (ou pas) par l'utilisateur est beaucoup, beaucoup plus simple. Cela peut être fait avec l'argument initial. SQL ne peut pas facilement transformer plusieurs lignes en une structure semblable à une grille. Cela nécessite soit un SQL sophistiqué (bien en dehors de la capacité de l'ORM), soit un traitement Python dans une fonction de vue.

  3. L'administrateur Django ne fera pas du tout de structure en grille.

+0

Ce n'est pas un design complet, je voulais juste simplifier la question et c'est la raison représentée de cette façon .... Et vous avez raison ce n'est pas une bonne idée de présenter la grille de cette façon, mais c'était juste l'une des options que j'avais ... –

+0

Pourriez-vous élaborer sur l'élément 2: Dynamic par défaut? Cette question de «dérogations» est quelque chose que j'ai rencontré et que je ne me suis jamais senti à l'aise de mettre en œuvre. Existe-t-il des articles qui explorent le problème ('sql overrides' est trop général pour que vous puissiez l'utiliser). – Koobz

+0

"Valeur par défaut dynamique" est simplement une valeur par défaut qui n'est pas définie de manière statique dans le modèle mais qui est chargée dynamiquement en fonction des données actuelles, de l'état de la transaction ou d'autre chose. C'est juste une valeur par défaut qui est chargée dynamiquement dans le formulaire lors de l'exécution. Lisez ceci: http://docs.djangoproject.com/en/dev/ref/forms/fields/#initial –

Questions connexes