关键字参数的Django反向匹配错误

时间:2018-07-31 10:15:12

标签: django python-3.6

我是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 %}

任何帮助将不胜感激。

1 个答案:

答案 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]+)\\/$']