Utilisation du code suivant: Essayer de SyncDB Donnez-moi cette erreur: P> Error: One or more models did not validate:
organizations.division: "unique_together" refers to alias. This is not in the
same model as the unique_together statement.
5 Réponses :
Ceci est par conception. Lire la documentation pour le option unique_together , il étage que: p>
Il est utilisé dans l'administrateur Django et est appliqué au niveau de la base de données fort>. p> blockQuote>
Si vous regardez la table qu'une sous-classe crée, vous verrez que cela ne réellement em> a les champs que son parent a. Au lieu de cela, il obtient une clé étrangère molle à la table des parents avec un nom de champ appelé
[champ] _ptr_id code>, où[champ] code> est le nom de la table que vous hériter d'exclure le nom de l'application. Donc, votre table de division a une clé étrangère primaire appeléeorganisation_ptr_id code>. P>Maintenant parce que
unique_together code> est appliqué au niveau de la base de données à l'aide de la contrainte code> unique code>, il n'y a aucun moyen que je connaisse pour la base de données pour appliquer réellement cela à un champ non dans la table. p>Votre meilleur pari est probablement via validateurs à votre entreprise-logique niveau ou repensez votre schéma de base de données pour prendre en charge la contrainte. p>
Edit: Comme MANOJ a souligné, vous pouvez également essayer d'utiliser validateurs de modèle tels que
validate_unique code>. P>
+1 pour mentionner pourquoi et relier les validateurs. Vous voudrez peut-être signaler Validations de modèle i> aussi. Par exemple, validate_unique code>: docs.djangoproject.com/fr/dev/ref/models/instances/...
[modèle] Les validateurs fonctionneraient pour vous. Peut-être plus simple, cependant, serait d'utiliser: Remarque: comme avec votre code actuel, vous ne pouvez pas avoir de subdivisions des divisions. P> P>
C'est une solution que j'ai récemment utilisée à Django 1.6 (grâce à Manoj Govindan pour l'idée):
class Organization(models.Model):
name = models.CharField(max_length="100",)
alias = models.SlugField()
...
class Division(Organization):
parent_org = models.ForeignKey(Organization)
# override Model.validate_unique
def validate_unique(self, exclude=None):
# these next 5 lines are directly from the Model.validate_unique source code
unique_checks, date_checks = self._get_unique_checks(exclude=exclude)
errors = self._perform_unique_checks(unique_checks)
date_errors = self._perform_date_checks(date_checks)
for k, v in date_errors.items():
errors.setdefault(k, []).extend(v)
# here I get a list of all pairs of parent_org, alias from the database (returned
# as a list of tuples) & check for a match, in which case you add a non-field
# error to the error list
pairs = Division.objects.exclude(pk=self.pk).values_list('parent_org', 'alias')
if (self.parent_org, self.alias) in pairs:
errors.setdefault(NON_FIELD_ERRORS, []).append('parent_org and alias must be unique')
# finally you raise the ValidationError that includes all validation errors,
# including your new unique constraint
if errors:
raise ValidationError(errors)
Évidemment, cela n'implique aucun contrôle de niveau de base de données, car une contrainte unique dans une table serait, mais en termes de validation de Django, cette solution a fonctionné de manière transparente pour moi. Celui que je devais corriger était de m'assurer d'exclure l'instance appelant validate_unique (donc exclure (pk = self.pk)).
Cela n'applique pas strictement la question mais est très étroitement lié; Cela empêchera Django de créer une table pour la classe et ses champs seront directement inclus dans toutes les sous-classes. Dans cette situation, https://docs.djangoproject.com/fr/1.5/topics/db/models/#AbRact-Base-classes p> p> unique_together code> fonctionnera si la classe de base est abstraite. Vous pouvez marquer des classes de modèle abstraites comme telles utilisez: unique_together code> est possible car tous les champs sont dans la même table. P>
J'ai eu un défi similaire pour essayer d'appliquer unique_together à un groupe d'autorisations créé par un client donné.
class ClientGroup(Group):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
is_active = models.BooleanField()
class Meta():
# looking at the db i found a field called group_ptr_id.
# adding group_ptr did solve the problem.
unique_together = ('group_ptr', 'client', 'is_active')
Pouvez-vous expliquer davantage l'exigence, incapable de comprendre quelle est la nécessité d'hériter d'une organisation et d'avoir une entreprise d'essence au même modèle de base.
C'est une simple relation parent-enfant une organisation peut avoir plusieurs divisions, une division est une sorte une organisation spécialisée.