J'ai récemment commencé à utiliser Django, alors soyez patient. J'ai un modèle avec 2 clés étrangères

class Application(models.Model): assessment_owner = models.ForeignKey(User, related_name='assessment_owner') creator = models.ForeignKey(User, related_name='creator')

J'essaie d'ajouter une nouvelle clé étrangère appelée tech_lead au même modèle, et la valeur par défaut de tech_lead devrait être assessment_owner. Plus tard, je peux mettre à jour la valeur de tech_lead en utilisant le chargement de données, mais au départ, il devrait être le propriétaire de l'évaluation.

Avec l'extrait de code suivant, Django demande une valeur par défaut lors des migrations et attribue le même tech_lead partout. Je voudrais définir la valeur par défaut de tech_lead via le code, et l'attribut par défaut simple ne fonctionne pas. J'ai essayé d'utiliser les signaux pre_save et post_save sans succès.

class Application(models.Model):
    assessment_owner = models.ForeignKey(User, related_name='assessment_owner')
    creator = models.ForeignKey(User, related_name='creator')
    tech_lead = models.ForeignKey(User, related_name='tech_lead')

J'utilise Django 1.11.3 et postgreSQL.

La migration a réussi avec une valeur par défaut unique.

Pile d'erreur -

Détails env

Erreur

Erreur

Merci d'avance.

2
Priyanka 19 mars 2019 à 13:17

2 réponses

Meilleure réponse

tech_lead = models.ForeignKey(User, related_name='tech_lead')

Rompt l'intégrité car votre base de données est déjà remplie d'instances Application. Si vous souhaitez ajouter un FK non nullable à votre schéma, vous devez spécifier la valeur par défaut. Sinon, si vous ne pouvez pas fournir de valeur par défaut, vous devriez envisager d'autoriser tech_lead à être NULL, c'est-à-dire:

tech_lead = models.ForeignKey(User, related_name='tech_lead', null=True)

Puis en utilisant migration de données pour remplir le champ avec les valeurs souhaitées :

from django.db import migrations

def populate_tech_lead(apps, schema_editor):
    Application = apps.get_model('yourappname', 'Application')
    for application in Application.objects.all():
        application.tech_lead = application.assessment_owner
        application.save()

class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(populate_tech_lead),
    ]

Puis en supprimant null=True du champ:

tech_lead = models.ForeignKey(User, related_name='tech_lead')

3
Kyryl Havrylenko 21 mars 2019 à 18:25

Étape 1. ajoutez null=True au champ tech_lead comme

class Application(models.Model):
    assessment_owner = models.ForeignKey(User, related_name='assessment_owner')
    creator = models.ForeignKey(User, related_name='creator')
    tech_lead = models.ForeignKey(User, related_name='tech_lead', null=True)

Étape 2. créez le fichier de migration par python manage.py makemigrations

Étape 3. migrez la base de données python manage.py migrate

Étape 4. ouvrez le shell Django, python manage.py shell

Étape 5. exécutez le script suivant

from your_app.models import Application
from django.db.models.expressions import F

Application.objects.filter(tech_lead__isnull=True).update(tech_lead=F('assessment_owner'))
1
JPG 19 mars 2019 à 10:28