我是python的新手,我正在接受培训以使用Django开发一个应用程序,以便在个人培训中心跟踪客户的问题。
我一直在解决未通过的关键字参数的反向匹配错误。老实说,我试图了解django如何成功管理此关键字参数。
django抛出的错误是:
NoReverseMatch at /persone/1/post
Reverse for 'cliente_detail' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['persone\\/(?P<pk>[0-9]+)\\/$']
Request Method: GET
Request URL: http://localhost:8000/persone/1/post
Django Version: 2.0.7
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'cliente_detail' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['persone\\/(?P<pk>[0-9]+)\\/$']
Exception Location: C:\Users\perso\Envs\djangodev\lib\site-packages\django\urls\resolvers.py in _reverse_with_prefix, line 636
Python Executable: C:\Users\perso\Envs\djangodev\Scripts\python.exe
Python Version: 3.6.4
Python Path:
['C:\\Users\\perso\\Dropbox\\Django\\Frame\\filo_project',
'C:\\Users\\perso\\Envs\\djangodev\\Scripts\\python36.zip',
'C:\\Users\\perso\\Envs\\djangodev\\DLLs',
'C:\\Users\\perso\\Envs\\djangodev\\lib',
'C:\\Users\\perso\\Envs\\djangodev\\Scripts',
'c:\\users\\perso\\appdata\\local\\programs\\python\\python36-32\\Lib',
'c:\\users\\perso\\appdata\\local\\programs\\python\\python36-32\\DLLs',
'C:\\Users\\perso\\Envs\\djangodev',
'C:\\Users\\perso\\Envs\\djangodev\\lib\\site-packages']
Server time: Mar, 31 Lug 2018 11:58:32 +0200
我的 views.py :
import json
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView
#Qui importo la classe per essere sicuro che se l'user non è loggato lo deve far loggare
from django.contrib.auth.decorators import login_required
#Ricordarsi di importare anche i modelli:
from .models import Cliente, FitCheck, Post
@login_required(login_url='/accounts/login/')
def home(request):
return render(request, "filogest/home.html")
class ClienteListView(LoginRequiredMixin, ListView):
#questa vista mi permette di visualizzare tutto l'elenco dei clienti
model = Cliente
template_name= "filogest/elenco_clienti.html"
#quetso per richiamare nel html il nome dell'elenco
context_object_name = 'elenco_clienti'
class ClienteDetailView(LoginRequiredMixin, DetailView):
model=Cliente
template_name="filogest/cliente_detail.html"
context_object_name = 'cliente_detail'
###############################
#Vai di editing di fitcheck
###############################
class FitcheckDetailView(LoginRequiredMixin, DetailView):
model=FitCheck
template_name="filogest/fitcheck_detail.html"
context_object_name = 'fitcheck_detail'
class FitcheckUpdateView(LoginRequiredMixin, UpdateView):
model = FitCheck
fields = ['idfitcheck','colazioneregolare']
template_name="filogest/fitcheck_update.html"
###############################
#Vai di editing di post
###############################
class PostDetailView(LoginRequiredMixin, DetailView):
model = Post
template_name="filogest/post_detail.html"
context_object_name = 'post_detail'
# def myPostListView(request, pk):
# idcli = get_object_or_404(Post, idclientepost=pk)
# posts_fisio = Post.objects.filter(tipologia="FI",idclientepost=idcli)
# posts_pale = Post.objects.filter(tipologia="PA",idclientepost=idcli)
# post = {"posts_fisio": posts_fisio, "posts_pale": posts_pale}
# return render(request, 'filogest/post_list.html', post)
class PostListView(LoginRequiredMixin, ListView):
model = Post
template_name = 'filogest/post_list.html'
context_object_name = 'post_list'
def get_context_data(self, *args, **kwargs):
context = super(PostListView, self).get_context_data(*args, **kwargs)
context['FisioPost'] = Post.objects.filter(tipologia="FI",idclientepost=self.kwargs['idclientepost'])
context['PalePost'] = Post.objects.filter(tipologia="PA",idclientepost=self.kwargs['idclientepost'])
context['fkPost'] = Post.objects.filter(idclientepost=self.kwargs['idclientepost'])
return context
class PostDetailCreate(LoginRequiredMixin, CreateView):
model = Post
template_name = 'post_create'
fields = '__all__'
###############################
#Vai di editing di post
###############################
#da controllare di brutto
def CercaPersona(request):
return render(request, "filogest/seleziona_cliente.html")
def AutocompleteCliente(request):
q = request.GET.get("term", "")
clienti = Cliente.objects.filter(nome__icontains=q)
results = []
for cliente in clienti:
place_json = {}
place_json = cliente.nome + " " + cliente.cognome
results.append(place_json)
data = json.dumps(results)
return HttpResponse(data, 'application/json')
models.py
from django.db import models
from django.contrib.auth.models import User
#importo timezone perchè così posso usare la funzione per capire quando è stato inserito
#un cliente oppure un fitcheck
from django.utils import timezone
from datetime import datetime
# Create your models here.
#questa funzione permette di far fare al sistema django i link per
#gli articoli referenziati
from django.urls import reverse
class Cliente(models.Model):
SESSO = (
('M','Maschio'),
('F','Femmina'),
)
idcliente = models.AutoField(primary_key=True)
nome = models.CharField(max_length=50)
cognome = models.CharField(max_length=50)
datadinascita = models.DateField()
sesso = models.CharField(max_length=1,choices=SESSO)
datainsert = models.DateTimeField(auto_now=True)
def __str__(self):
return self.cognome + " " + self.nome
def age(self):
return int((datetime.now().date() - self.datadinascita).days / 365.25)
#Qui uso questa funzione per far gestire al sistema i link che andro poi a richiamare
#con la classe.get_absolute_url
def get_absolute_url(self):
return reverse("filogest:cliente_detail", kwargs={"pk":self.idcliente})
class Meta:
# link utile : https://docs.djangoproject.com/en/2.0/ref/models/options/
verbose_name = "Cliente"
verbose_name_plural = "Clienti"
class FitCheck(models.Model):
STILE_PROFESSIONE = (
('PA','Poco attiva'),
('MA','Mediamente attiva'),
('A', 'Attiva'),
('MM','Molto Attiva'),
('US','Usurante'),
)
SI_NO = (
('S','Si'),
('N','No'),
)
ALIMENTAZIONE_TIPO = (
('D','Dietologo'),
('F', 'Fai da te'),
('N', 'Nutrizionista'),
('O', 'Nulla'),
)
STILE_DI_VITA = (
('PA','Poco Attivo'),
('MA', 'Mediamente Attivo'),
('AA', 'Attivo'),
('AM', 'Molto Attivo'),
('US', 'Usurante'),
)
OBIETTIVO_PRIMARIO = (
('DI','Dimagrimento'),
('PE', 'Performance'),
('DO', 'Dolore'),
('MU', 'Muscolazione'),
('FI', 'Fitness Generale'),
('GR', 'Gravidanza'),
('PG', 'Post Gravidanza'),
('PO', 'Postura'),
('RI', 'Rieducazione'),
('OP', 'Pre-Intervento'),
('CV', 'Cardio Vascolare'),
('PM', 'Prescrizione Medica'),
)
HA_DOLORE = (
('A','Acuto'), #dall'ultima settimana ha dolore
('S','Sub-acuto'), #dalla fase di dolore a 6 settimane
('C','Cronico'),
('N','No')
)
PROFESSIONE = (
('A','Altro'),
('C','Casalinga'),
('I','Impiegato'),
('O','Operaio'),
('S','Sportivo'),
('U','Studente'),
('P','Pensionato'),
('L','Libero Professionista'),
('T','Autista'),
)
STRESS = (
('PS','Poco Stressante'),
('ST','Stressante'),
('MS','Molto Stressante'),
)
DISP_ORARIA = (
('MA','Mattina'),
('PP','Pausa Pranzo'),
('PO','Pomeriggio'),
('SE','Sera'),
('TU','Turni'),
('LI','Libero'),
)
PROPOSTA_ACCETTATA = (
('S','Si'),
('N','No'),
('F','Fa Sapere'),
)
OSTEO = (
('F','Fatta'),
('D','Da Fare'),
('N','No'),
)
FONTE = (
('MA','Mattia'),
('PC','Paolo Cucchetti'),
('FD','Federico Dal Corso'),
('IN','Insegna'),
('IT','Internet'),
('UM','Monsellato'),
('MC','Marco'),
('PR','Paolo Roma'),
('TR','Trainer'),
('CL','Clienti'),
('MD','Medici'),
('AM','Amicizie'),
('VA','Varie'),
)
EFFETTUATO_DA = (
('MP','Marco P'),
('PR','Paolo R'),
('MA','Marco A'),
('PC','Paolo C'),
)
FUMATORE = (
('SI','Si'),
('ST','Saltuariamente'),
('NO','No'),
('EX','Ex'),
)
VAS = (
('0','0'),
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
('8','8'),
('9','9'),
('10','10')
)
idfitcheck = models.OneToOneField(Cliente, on_delete=models.CASCADE, primary_key=True)
luogodinascita = models.CharField(max_length=50, verbose_name="Luogo di nascita")
email = models.EmailField(verbose_name="E-mail")
telefono = models.CharField(max_length=20, verbose_name="Numero di telefono")
indirizzo = models.CharField(max_length=100, verbose_name="Indirizzo")
citta = models.CharField(max_length=20, verbose_name="Città")
cap = models.CharField(max_length=5, verbose_name="CAP")
figli = models.CharField(max_length=50, verbose_name="Figli")
professione = models.CharField(max_length=1,choices=PROFESSIONE, verbose_name="Professione")
stileprofessione = models.CharField(max_length=2,choices=STILE_PROFESSIONE, verbose_name="Stile Professione")
stiledivita = models.CharField(max_length=2,choices=STILE_DI_VITA, verbose_name="Stile di vita")
stress = models.CharField(max_length=2,choices=STRESS, verbose_name="Come definisce il suo stile di vita?")
fumatore = models.CharField(max_length=2, choices=FUMATORE, verbose_name="Fuma?")
obiettivoprimario = models.CharField(max_length=2,choices=OBIETTIVO_PRIMARIO, verbose_name="Obiettivo Primario")
noteprimario = models.TextField(verbose_name="Note obiettivo primario")
obiettivosecondario = models.TextField(verbose_name="Obiettivo secondario")
alimentazione = models.CharField(max_length=2,choices=ALIMENTAZIONE_TIPO, verbose_name="Cura alimentazione")
alimcontrollataattiva = models.CharField(max_length=2,choices=SI_NO, verbose_name="Attualmente l'alimentazione è controllata")
pastialgiorno = models.IntegerField(verbose_name="Quanti pasti fa al giorno?")
colazioneregolare = models.CharField(max_length=2,choices=SI_NO, verbose_name="Fa colazione regolarmente?")
giabia = models.CharField(max_length=2,choices=SI_NO,verbose_name="Ha già fatto test BIA?")
attivitaattuali = models.CharField(max_length=2,choices=SI_NO,verbose_name="Attualmente svolge attività fisiche?")
attivitafisicarecente = models.CharField(max_length=500, verbose_name="Attività fisiche recenti")
attivitapassato = models.CharField(max_length=2,choices=SI_NO, verbose_name="In passato ha svolto attività?")
qualiattivita = models.CharField(max_length=500,verbose_name="Se si quali?")
assumealcool = models.CharField(max_length=2,verbose_name="Assume alcool?", choices=FUMATORE)
quantitaalcol = models.FloatField(verbose_name="Quanti bicchieri beve al giorno?")
attualmenteagonista = models.CharField(max_length=2,choices=SI_NO, verbose_name="Attualmente Agonista")
hadolore = models.CharField(max_length=2,choices=HA_DOLORE, verbose_name="Attualmente ha dolore?")
vasnrs = models.CharField(max_length=1, choices=VAS, verbose_name="Scala vas del dolore acuto e sub-acuto")
doloripassati = models.CharField(max_length=2,choices=SI_NO, verbose_name="Dolori in passato?")
notedoloripassati = models.TextField(verbose_name="Note su dolori")
traumipassati = models.CharField(max_length=2,choices=SI_NO, verbose_name="Ha subito traumi in passato")
interventichirurgici = models.CharField(max_length=2,choices=SI_NO)
notetraumiinterventi = models.TextField(verbose_name="Note traumi/interventi")
altremalattie = models.TextField(verbose_name="Altre malattie?")
altro = models.TextField(verbose_name="Altro da segnalare?")
disponibilitaoraria = models.CharField(max_length=2,choices=DISP_ORARIA)
freqsettimanale = models.FloatField(verbose_name="Quante volte riuscirebbe a venire regolarmente?")
seduteproposte = models.IntegerField(verbose_name="Sedute proposte dal trainer")
propostaaccettata = models.CharField(max_length=1,choices=PROPOSTA_ACCETTATA, verbose_name="Proposta fatta dal trainer accettata?")
fonte = models.CharField(max_length=2,choices=FONTE, verbose_name="Fonte")
sedutaprova = models.CharField(max_length=2,choices=SI_NO, verbose_name="Seduta di prova fissata?")
totaleeconomico = models.FloatField(verbose_name="Totale economico proposto?")
biaprogrammata = models.CharField(max_length=1,choices=OSTEO, verbose_name="Bia programmata?")
osteoprogrammata = models.CharField(max_length=1,choices=OSTEO, verbose_name="Valutazione osteopatica programmata?")
fisioprogrammata = models.CharField(max_length=1,choices=OSTEO, verbose_name="Valutazione fisioterapica programmata?")
stapedio = models.CharField(max_length=2,choices=SI_NO)
datainserimento= models.DateTimeField(auto_now=True)
effettuato = models.CharField(max_length=2, choices=EFFETTUATO_DA, verbose_name="Colloquio effettuato da?")
def __str__(self):
return self.idfitcheck.cognome + " "+ self.idfitcheck.nome
def nome_persona(self):
return self.idfitcheck.cognome + " "+ self.idfitcheck.nome
def fitchekpk(self):
return self.idfitcheck
def get_absolute_url(self):
return reverse("filogest:fitcheck_detail", kwargs={"pk":self.idfitcheck})
class Meta:
# link utile : https://docs.djangoproject.com/en/2.0/ref/models/options/
verbose_name = "FitCheck"
verbose_name_plural = "FitChecks"
#da qui parte lo script per il modello di balke che prendere:
#1- età
#2-SESSO
#3-Peso che va creato ad ok
#4- da qui calcolare poi la frequenza cardiaca massima
#5- permettere l'inserimento dei dati del test
#6- elaborare e salvare i risultati
class Balke(models.Model):
idbalke = models.ForeignKey(Cliente,on_delete=models.CASCADE, related_name="filogest_balke_clienti")
etasogg = models.IntegerField()
pesosogg = models.FloatField()
blocco1=models.IntegerField()
blocco2=models.IntegerField()
blocco3=models.IntegerField()
blocco4=models.IntegerField()
blocco5=models.IntegerField()
blocco6=models.IntegerField()
blocco7=models.IntegerField()
def __str__ (self):
return self.idbalke.cognome + " "+ self.idbalke.nome
def cooper(self):
return 220-Cliente.age
def tanaka(self):
return (208-(0,7*Cliente.age))
class Post(models.Model):
OBIETTIVO_PERSONA = (
('DI','Dimagrimento'),
('PE', 'Performance'),
('DO', 'Dolore'),
('MU', 'Muscolazione'),
('FI', 'Fitness Generale'),
('GR', 'Gravidanza'),
('PG', 'Post Gravidanza'),
('PO', 'Postura'),
('RI', 'Rieducazione'),
('OP', 'Pre-Intervento'),
('CV', 'Cardio Vascolare'),
('PM', 'Prescrizione Medica'),
)
TIPO = (
('FI', 'Fisio / Osteo'),
('PA', 'Palestra'),
)
idpost = models.AutoField(primary_key=True)
idclientepost = models.ForeignKey(Cliente, on_delete=models.CASCADE, related_name="cliente")
tipologia = models.CharField(max_length=2, choices=TIPO)
titolo = models.CharField(max_length=250)
obiettivo = models.CharField(max_length=2, choices=OBIETTIVO_PERSONA)
autore = models.ForeignKey(User, on_delete=models.CASCADE,related_name="filogest_post")
corpo = models.TextField()
creato = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-creato',)
def get_absolute_url(self):
return reverse("filogest:post_detail", kwargs={"idclientepost": self.idclientepost.idcliente, "pk":self.idpost})
return reverse("filogest:post_list", kwargs={"idclientepost": self.idclientepost.idcliente})
def __str__(self):
return self.titolo
Urls.py :
from django.urls import path, include, reverse
from .views import home, ClienteListView, ClienteDetailView, AutocompleteCliente, CercaPersona, FitcheckDetailView, FitcheckUpdateView
from .views import PostListView, PostDetailView, PostListView
app_name='filogest'
urlpatterns = [
path ('', home, name='homepage'),
path ('persone/', ClienteListView.as_view(), name='elenco_clienti'),
path ('persone/<int:pk>/', ClienteDetailView.as_view(), name='cliente_detail'),
path ('getperson/', AutocompleteCliente, name='autocomplete_cliente'),
path ('cercaper/', CercaPersona, name='cerca_persona'),
path ('persone/<int:pk>/fitcheck', FitcheckDetailView.as_view(), name='fitcheck_detail'),
path ('persone/<int:pk>/fitcheckupdate', FitcheckUpdateView.as_view(), name='fitcheck_update'),
#uso idcliente post perchè il modello è il post ma il riferimento è la chiave esterna
path ('persone/<int:idclientepost>/post', PostListView.as_view(), name='post_list'),
path ('persone/<int:idclientepost>/post/<int:pk>',PostDetailView.as_view(), name='post_detail'),
]
cliente_detail模板
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block head_title %}{{ block.super }} - Dettagli Cliente{% endblock head_title %}
{% block content %}
<br>
<div class="">
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:cliente_detail' pk=cliente_detail.idcliente %}';">Dettagli Anagrafici</button>
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:fitcheck_detail' pk=cliente_detail.idcliente %}';">FitCheck</button>
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:post_list' idclientepost=cliente_detail.idcliente %}';">Note operative</button>
<button type="button" class="btn btn-primary">Test Balke</button>
<button type="button" class="btn btn-primary">Test Motori</button>
</div>
<br>
<div class="alert alert-warning" role="alert">
<br>
<h1>Dettagli persona:</h1>
<hr>
<strong>Cognome:</strong> {{ cliente_detail.cognome }} <br>
<strong>Nome:</strong> {{ cliente_detail.nome }} <br>
<strong>Data di nascita:</strong> {{ cliente_detail.datadinascita }} <br>
<strong>Sesso:</strong> {{ cliente_detail.sesso }} <br>
<strong>Età:</strong> {{ cliente_detail.age }} <br>
<hr>
</div>
{% endblock content %}
post_list
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block head_title %}{{ block.super }} - Dettagli Cliente{% endblock head_title %}
{% block content %}
<br>
<div class="">
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:cliente_detail' pk=post_list.idclientepost %}';">Dettagli Anagrafici</button>
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:fitcheck_detail' pk=1 %}';">FitCheck</button>
<button type="button" class="btn btn-primary">Note operative</button>
<button type="button" class="btn btn-primary">Test Balke</button>
<button type="button" class="btn btn-primary">Test Motori</button>
</div>
<div>
<br>
<h1>Commenti di {% for post in fkPost %}
{% if forloop.first %}
{{ post.idclientepost.cognome }} {{ post.idclientepost.nome}}
{% endif %}
{% endfor %}</h1>
<div class="container">
<div class="row">
<div class="col">
<h2>Note Osteofisio :</h2>
<br>
{% for post in FisioPost %}
<div class="p-2 border border-primary">
<strong>Titolo:</strong> <a href="{{ post.get_absolute_url }}">{{ post.titolo }} </a><br>
<strong>Obiettivo:</strong> {{post.get_obiettivo_display}} <br>
<div class="p-1 border">
<strong>Nota:</strong><br>
{{post.corpo}}<br>
</div>
<i>Creato da: <strong>{{post.autore}}</strong> in data {{post.creato}}</i>
{{post.idclientepost}}
</div>
{% endfor %}
</div>
<div class="col">
<h2>Note Trainer:</h2>
<br>
{% for post in PalePost %}
<div class="p-2 border border-success">
<strong>Titolo:</strong> <a href="{{ post.get_absolute_url }}">{{ post.titolo }} </a><br>
<strong>Obiettivo:</strong> {{post.get_obiettivo_display}} <br>
<div class="p-1 border">
<strong>Nota:</strong><br>
{{post.corpo}}<br>
</div>
<i>Creato da: <strong>{{post.autore}}</strong> in data {{post.creato}}</i>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
任何帮助将不胜感激。
答案 0 :(得分:0)
据我所见,此异常在PostListView
处引发。在模板filogest/post_list.html
中,您有一个详细信息按钮:
<button type="button" class="btn btn-primary" onclick="location.href='{% url 'filogest:cliente_detail' pk=post_list.idclientepost %}';">Dettagli Anagrafici</button>
您正在使用参数pk=post_list.idclientepost
创建URL。我相信实例中的post_list.idclientepost
可能为null或空白。正如错误中提到的,pk传递为空白(with keyword arguments '{'pk': ''}'
)。
Reverse for 'cliente_detail' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['persone\\/(?P<pk>[0-9]+)\\/$']