Lier framework Django ContentType via des URL
-
24-10-2019 - |
Question
J'ai questionnaire application qui permet la création de dynamique d'un formulaire. Dans mon système actuel, je le relier à un projet. Voici un exemple de mes modèles. Je veux séparer l'application du questionnaire complètement de dépendances des autres applications dans mon projet en cours de django.
#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)
Dans mes questionnaire.views, pour cet exemple, Ihave deux fonctions de base Question_set créer et créer des questions. Dans la Question_set créer la fonction que j'ai une forme qui me permet d'ajouter des questions créées à l'Question_set puis enregistrez le Question_set. Actuellement, je passe aussi le project_id dans l'URL pour ce point de vue que je puisse obtenir l'instance du projet et ajouter le 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"),
Je crois que la solution consiste à Django ContentType cadre mais je je ne suis pas sûr que la meilleure façon de s'y prendre pour passer la classe modèle via l'URL. Donc, si le Question_set devait être sauvé au modèle Foo à la place du projet. Comment dans l'URL que j'identifier la classe modèle?
La solution
Je pense que le problème peut être la façon dont vous avez organisé vos modèles. Je voudrais aussi éviter l'utilisation d'un nom de modèle se terminant par _set
car cela pourrait être très déroutant. Qu'en est-il ceci:
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()
Une fois que vous avez clairement défini le questionnaire comme son propre modèle complet, la création d'une URL devient plus simple:
#questionnaire.urls
#pattern for question_set_create
url(r'^(?P<content_type>[-\w]+)/(?P<object_id>[-\w]+)/add_set/$', 'questionnaire_create' , name="questionnaire_create"),
Où content_type est le nom du type de contenu (par exemple, « projects.project » ou quelque chose de similaire) et id_objet la clé primaire de l'enregistrement correspondant.
l'URL équivalent pour la création d'un questionnaire pour l'identification du projet n ° 1 serait /questionnaires/projects.project/1/add_set/