web-dev-qa-db-fra.com

ForeignKey n'autorise pas les valeurs nulles

J'utilise le Django REST Framework 2.0.

Voici ma classe de modèle:

class Mission(models.Model):
    assigned_to = models.ForeignKey('auth.User',
                                    related_name='missions_assigned',
                                    blank = True)

Voici ma classe de vue:

class MissionList(generics.ListCreateAPIView):
    model = Mission
    serialize_class = MissionSerializer
  1. Le formulaire en plusieurs parties est rendu dans le navigateur avec un choix vide pour assigned_to champ.

  2. Lors de la publication de JSON brut, j'obtiens le message d'erreur suivant:

Cannot assign None: "Mission.assigned_to" does not allow null values.

31
Benjamin Toueg

L'option blank est utilisée dans la validation du formulaire et null est utilisée lors de l'écriture dans la base de données.

Vous pouvez donc ajouter null=True à ce champ.

EDIT: continuer le commentaire

Considérant les deux étapes lors de l'enregistrement de l'objet:

  1. Validateur (contrôlé par blank)
  2. Limitation de la base de données (contrôlée par null)

Pour l'option default, prenez IntegerField par exemple,
default=5, blank=True, null=False, passez (1) même si vous n'avez pas affecté de valeur (ayant blank=True), passez (2) car il a une valeur par défaut (5) et écrit 5 au lieu de None dans DB.
blank=True, null=False, qui passe (1) mais pas (2), car il tente d'écrire None dans DB.

Ainsi, si vous souhaitez rendre un champ facultatif, utilisez soit default=SOMETHING, blank=True, null=False ou blank=True, null=True.

Une autre exception est le champ de type chaîne, tel que CharField.
Il est suggéré d'utiliser le blank=Trueseul, laissant null=False derrière.
Cela fait un champ soit une chaîne (> = 1 caractère (s)) ou une chaîne vide ('', avec len () == 0), et jamais None.

La raison en est que lorsque null=True est défini, il y aura deux valeurs possibles pour l'état "unset": chaîne vide et None, ce qui prête à confusion (et peut provoquer des bugs).

82
user1034937

ForeignKey autorise les valeurs nulles si ce comportement a été défini. Votre code ressemblera à ceci:

class Mission(models.Model):
    assigned_to = models.ForeignKey(
        'auth.User',
        related_name='missions_assigned',
        blank=True,
        null=True
    )

Vous devez écrire null=True.

Remarque: après avoir modifié un modèle, vous devez exécuter python manage.py makemigrations yourappname et alors python manage.py migrate

7
shmakovpn