Collegamento quadro Django ContentType tramite URL
-
24-10-2019 - |
Domanda
Ho questionario app che permette la creazione dinamica di un modulo. Nel mio sistema corrente I collegarlo a un progetto. Ecco un esempio dei miei modelli. Voglio separare completamente l'applicazione questionario dalle dipendenze delle altre applicazioni nel mio progetto Django corrente.
#project.models
class Project(models.Model):
name = models.CharField(max_length.....
category = models.CharField(max_length
question_sets = models.ManyToManyField(Question_Set)
#questionnaire.models
class Question(models.Model):
question = models.CharField(max_length....
question_type = models.IntegerField(choices=.....
class Question_set(models.Model):
name = models.CharField(....
questions = models.ManyToManyField(Question)
All'interno miei questionnaire.views, per questo esempio, Ihave due funzioni di base Question_set creare e domanda creare. Nel Question_set creare funzione di Ho una forma che mi permette di aggiungere domande create al Question_set e quindi salvare le Question_set. Attualmente passo anche la project_id nell'url questo punto di vista in modo da poter ottenere l'istanza progetto e aggiungere il Question_set
#questionnaire.views
def question_set_create(request, project_id, form_class=AddSetForm, template_name=....):
if request.method = "POST":
form = form_class(request.POST)
if form.is_valid():
set = form.save()
project = Project.objects.get(id=project_id)
project.question_sets.add(set)
....
#questionnaire.urls
#pattern for question_set_create
url(r'^(?P<project_id>[-\w]+)/add_set/$', 'questionnaire_create' , name="project_questionnaire_create"),
Credo che la soluzione comporta il Django ContentType quadro ma io non sono sicuro che il modo migliore per andare a passare la classe del modello tramite l'url. Quindi, se il Question_set doveva essere salvata modello Foo invece di progetto. Come in tutto l'URL avrei identificare la classe del modello?
Soluzione
Credo che il problema può essere nel modo in cui hai organizzato le tue modelli. Vorrei anche evitare l'uso di un nome del modello che termina in _set
in quanto ciò potrebbe ottenere molto confuso. Che dire di questo, invece:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from questionnaire.models import Questionnaire
#project.models
class Project(models.Model):
name = models.CharField(max_length.....
category = models.CharField(max_length
questionnaires = generic.GenericRelation(Questionnaire)
#questionnaire.models
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Question(models.Model):
question = models.CharField(max_length....
question_type = models.IntegerField(choices=.....
class Questionnaire(models.Model):
name = models.CharField(...)
questions = models.ManyToManyField(Question)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
Una volta che avete definito chiaramente il questionario come proprio modello completo, la creazione di un URL diventa più semplice:
#questionnaire.urls
#pattern for question_set_create
url(r'^(?P<content_type>[-\w]+)/(?P<object_id>[-\w]+)/add_set/$', 'questionnaire_create' , name="questionnaire_create"),
Dove content_type è il nome del tipo di contenuto (per esempio, 'projects.project' o qualcosa di simile) e object_id è la chiave primaria del record corrispondente.
Quindi, l'URL equivalente per la creazione di un questionario per il progetto ID # 1 sarebbe /questionnaires/projects.project/1/add_set/