I have a custom form form signup, referencing a "categorie" model on a modelChoiceField. As I try to submit it, it fails on getting the reference to the model and raises the following error :
IntegrityError at /marketplace/signsupplier/ null value in column "categorie_id" violates not-null constraint DETAIL: Failing row contains (55, , , , , , null).
It's as if it loses all posted datas, but I can see in the debug that categorie_id is well passed in the POST datas.
Here is my model.py :
class Supplier(models.Model):
phone_regex = RegexValidator(regex=r'^(87|89)\d{6}$', message="Entrez un numéro de portable Polynésien valide")
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
enseigne = models.CharField(max_length=128, blank=False, null=False)
vini = models.CharField(verbose_name="Vini",validators=[phone_regex], max_length=8, blank=False, null=False)
numero_tahiti = models.CharField(max_length=9, blank=False, null=False)
immat_rcs = models.CharField(max_length=9, blank=False, null=False)
categorie = models.ForeignKey(Categorie, on_delete=models.DO_NOTHING)
labels = models.CharField(max_length=128)
my forms.py :
class SignupSupplierForm(UserCreationForm):
email = forms.EmailField(required=True)
first_name = forms.CharField(required=True,label="Prenom")
last_name = forms.CharField(required=True,label="Nom")
vini = forms.CharField(required=True, max_length=8,validators=[phone_regex])
enseigne = forms.CharField(required=True, max_length=128, label="Enseigne")
numero_tahiti = forms.CharField(required=True, max_length=9, label="Numéro Tahiti")
immat_rcs = forms.CharField(required=True, max_length=9, label="Immatriculation RCS")
categorie = forms.ModelChoiceField(required=False,queryset=Categorie.objects.all())
labels = forms.CharField(required=False,max_length=128, label="Labels (option)")
class Meta(UserCreationForm.Meta):
model = User
fields = ('email','first_name','last_name')
@transaction.atomic
def save(self):
user = super().save(commit=False)
user.is_supplier = True
user.save()
supplier = Supplier.objects.create(user=user)
supplier.vini = self.cleaned_data.get('vini')
supplier.enseigne = self.cleaned_data.get('enseigne')
supplier.numero_tahiti = self.cleaned_data.get('numero_tahiti')
supplier.immat_rcs = self.cleaned_data.get('immat_rcs')
supplier.categorie = self.cleaned_data['categorie'].id
supplier.labels = self.cleaned_data.get('labels')
supplier.save()
return user
And views.py
class SignupSupplierView(CreateView):
model = User
form_class = SignupSupplierForm
success_url = reverse_lazy('home')
template_name = 'signup.html'
def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs)
def form_valid(self, form):
user = form.save()
login(self.request, user)
return HttpResponseRedirect(self.success_url)
I know it's a problem with the "categorie" field, but can't figure out how to make ot work.
As asked, here is the content of the POST data, from the debug panel :
Variable Value
csrfmiddlewaretoken 'TGTAW...qn17h'
email '[email protected]'
first_name 'pre four'
last_name 'nom four'
password1 'test456'
password2 'test456'
vini '87740921'
enseigne 'ens four'
numero_tahiti '123456789'
immat_rcs '123456789'
categorie '2'
labels 'test'
I also used logging features to get more informations on the error, and I got this. Maybe it could help :
(0.001) DECLARE "_django_curs_139721501058880_sync_1" NO SCROLL CURSOR WITH HOLD FOR SELECT "ELIEN_CORE_categorie"."id", "ELIEN_CORE_categorie"."categorie", "ELIEN_CORE_categorie"."timestamp", "ELIEN_CORE_categorie"."updated" FROM "ELIEN_CORE_categorie"; args=()
Exception while resolving variable 'object_list' in template 'signup.html'.
and then, a little bit further :
Traceback (most recent call last):
File "/home/max/elien_dev/elien/lib/python3.8/site-packages/django/template/base.py", line 848, in _resolve_lookup
raise VariableDoesNotExist("Failed lookup for key "
django.template.base.VariableDoesNotExist: Failed lookup for key [mapbox_key] in [{'True': True, 'False': False, 'None': None}, {'csrf_token': <SimpleLazyObject: '96lE9Cepu2rqn5MbTGqtqmLdsz0LY1dGodSUIsOlqhU1bMj78EZzmLryqI8o7bkU'>, 'request': <WSGIRequest: GET '/marketplace/signsupplier/'>, 'user': <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7f1cee9b9850>>, 'perms': <django.contrib.auth.context_processors.PermWrapper object at 0x7f1cee92d580>, 'messages': <django.contrib.messages.storage.fallback.FallbackStorage object at 0x7f1ceea002e0>, 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}}, {}, {'form': <SignupSupplierForm bound=False, valid=False, fields=(email;first_name;last_name;password1;password2;vini;enseigne;numero_tahiti;immat_rcs;categorie;labels)>, 'view': <ELIEN_MARKETPLACE.views.SignupSupplierView object at 0x7f1ceea00370>}, {}]
(0.001) SELECT "ELIEN_CORE_categorie"."id", "ELIEN_CORE_categorie"."categorie", "ELIEN_CORE_categorie"."timestamp", "ELIEN_CORE_categorie"."updated" FROM "ELIEN_CORE_categorie" WHERE "ELIEN_CORE_categorie"."id" = 3 LIMIT 21; args=(3,)
(0.001) SELECT (1) AS "a" FROM "ELIEN_CORE_user" WHERE "ELIEN_CORE_user"."email" = '[email protected]' LIMIT 1; args=('[email protected]',)
(0.001) INSERT INTO "ELIEN_CORE_user" ("password", "last_login", "is_superuser", "first_name", "last_name", "is_staff", "is_active", "date_joined", "email", "email_confirmed", "is_client", "is_supplier") VALUES ('p...w=', NULL, false, 'pre four', 'nom four', false, true, '2020-12-08T07:04:56.897584+00:00'::timestamptz, '[email protected]', false, false, true) RETURNING "ELIEN_CORE_user"."id"; args=('p...=', None, False, 'pre four', 'nom four', False, True, datetime.datetime(2020, 12, 8, 7, 4, 56, 897584, tzinfo=<UTC>), '[email protected]', False, False, True)
(0.001) INSERT INTO "ELIEN_MARKETPLACE_supplier" ("user_id", "enseigne", "vini", "numero_tahiti", "immat_rcs", "categorie_id", "labels") VALUES (63, '', '', '', '', NULL, ''); args=(63, '', '', '', '', None, '')
(0.000) SELECT "ELIEN_MARKETPLACE_supplier"."user_id", "ELIEN_MARKETPLACE_supplier"."enseigne", "ELIEN_MARKETPLACE_supplier"."vini", "ELIEN_MARKETPLACE_supplier"."numero_tahiti", "ELIEN_MARKETPLACE_supplier"."immat_rcs", "ELIEN_MARKETPLACE_supplier"."categorie_id", "ELIEN_MARKETPLACE_supplier"."labels" FROM "ELIEN_MARKETPLACE_supplier" LIMIT 21; args=()
(0.000) SELECT "ELIEN_MARKETPLACE_supplier"."user_id", "ELIEN_MARKETPLACE_supplier"."enseigne", "ELIEN_MARKETPLACE_supplier"."vini", "ELIEN_MARKETPLACE_supplier"."numero_tahiti", "ELIEN_MARKETPLACE_supplier"."immat_rcs", "ELIEN_MARKETPLACE_supplier"."categorie_id", "ELIEN_MARKETPLACE_supplier"."labels" FROM "ELIEN_MARKETPLACE_supplier" LIMIT 21; args=()
Internal Server Error: /marketplace/signsupplier/
Traceback (most recent call last):
File "/home/max/elien_dev/elien/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.NotNullViolation: null value in column "categorie_id" violates not-null constraint
DETAIL: Failing row contains (63, , , , , , null).
Thanks for your help !
Here is the issue,
self.cleaned_data['categorie'] itself contains the id of categorie instance, so you don't need to do
just