IntegrityError al vincolo ** NOT NULL non riuscito: learning_logs_topic.owner_id

Integrityerror Not Null Constraint Failed



Recentemente, stavo imparando il capitolo 19 di 'Python from Getting Started to Actual Combat'. Nel modello learning_logs, è stato aggiunto l'attributo utente dell'argomento, ovvero l'argomento creato dopo il quale l'utente ha effettuato l'accesso. Quindi l'attributo del proprietario di questo argomento è l'utente connesso. .ForeignKey (User, on_delete = models.CASCADE), il proprietario è la chiave esterna dell'utente (pthon versione 3.7.4, django versione 2.2.6) e dopo makemigrations viene visualizzato il seguente prompt:



A questo punto, seleziona l'opzione '1)', quindi seleziona l'ID utente 1, che è ll_admin. In questo momento, l'ID utente originale dell'argomento originale è 1, che è ll_admin. Il seguente errore si è verificato durante l'esecuzione di new_topic:



IntegrityError al vincolo / new_topic / NOT NULL non riuscito: learning_logs_topic.owner_id, la scena dell'errore è la seguente:



Il codice sorgente del modello di argomento è il seguente:

class Argomento (models.Model):
text = models.CharField (max_length = 200)
date_added = models.DateTimeField (auto_now_add = True)
proprietario = models.ForeignKey (User, on_delete = models.CASCADE)
def __str __ (self):
return self.text



Il codice sorgente di topicform è il seguente:

class TopicForm (forms.ModelForm):
classe Meta:
modello = Argomento
campi = ['testo']
etichette = {'text': ''}

Il codice sorgente new_topic di views.py nella cartella learning_logs è il seguente:

def new_topic (richiesta):
if request.method! = 'POST':
form = TopicForm ()

altro :
form = TopicForm (request.POST)
se form.is_valid ():
form.save ()
return HttpResponseRedirect (reverse ('learning_logs: topics'))

context = {'form': form}
restituire il rendering (richiesta, 'learning_logs / new_topic.html', contesto)

Questo errore mostra l'errore del limite di valore nullo: proprietario, proprietario è l'attributo appena aggiunto nei modelli. Sebbene l'attributo del proprietario venga aggiunto all'argomento esistente, l'argomento appena aggiunto non ha alcun attributo del proprietario, quindi viene segnalato un errore.

Il processo di risoluzione è il seguente:

(1) Aggiungere null = True all'attributo models.py per consentire a questo attributo di essere vuoto

Dopo la modifica, diventa owner = models.ForeignKey (User, on_delete = models.CASCADE, null = True), l'errore non viene più visualizzato dopo la modifica, ma il proprietario dell'argomento appena aggiunto è NULL, che non è ciò che il design desideri

(2) Aggiungi valori predefiniti in models.py.

Dopo la modifica, owner = models.ForeignKey (User, on_delete = models.CASCADE, default = 1), l'errore non apparirà dopo la modifica, ma il proprietario dell'argomento appena aggiunto è l'utente con ID 1, che non è quello che i desideri di design.

(3) Modifica TopicForm e aggiungi il campo del proprietario

Dopo la modifica, TopicForm diventa il seguente:

class TopicForm (forms.ModelForm):
classe Meta:
modello = Argomento
fields = ['text ,' owner ']
etichette = {'text': '', 'owner': ''}

Dopo la modifica, l'utente selezionerà il proprietario di questo argomento appena creato come segue:

Sebbene l'utente attualmente connesso possa essere selezionato come proprietario di questo argomento, l'utente può anche selezionare altri utenti non attualmente connessi, aumentando il rischio di errori

(4) Nella vista views.py new_topic, usa request.user per ottenere l'utente corrente e assegnarlo al modulo

Cioè, aggiungi una riga dopo if form.is_valid ():

form.instance.owner = request.user, dopo la modifica, diventa:

def new_topic (richiesta):
if request.method! = 'POST':
form = TopicForm ()

altro :
form = TopicForm (request.POST)
se form.is_valid ():
form.instance.owner = request.user
form.save ()
return HttpResponseRedirect (reverse ('learning_logs: topics'))

context = {'form': form}
restituire il rendering (richiesta, 'learning_logs / new_topic.html', contesto)

Vale a dire, utilizzare il parametro di istanza di Form per ottenere l'attributo owner e assegnare l'utente corrente ottenuto da requset.user al proprietario di questa istanza. Il programma modificato realizza la funzione predeterminata

(5) Viene utilizzato anche il parametro di istanza, ma quando viene generato il modulo, la vista new_topic modificata è la seguente:

def new_topic (richiesta):
if request.method! = 'POST':
form = TopicForm ()

altro :
form = TopicForm (request.POST)
topic = Argomento ()
topic.owner = request.user
form = TopicForm (request.POST, instance = topic)
se form.is_valid ():
form.save ()
return HttpResponseRedirect (reverse ('learning_logs: topics'))

context = {'form': form}
restituire il rendering (richiesta, 'learning_logs / new_topic.html', contesto)

Prima genera un argomento, quindi assegnalo al proprietario, quindi assegna questo argomento al parametro di istanza, il costo di spazio e tempo è elevato, ma raggiunge anche la funzione predeterminata.