通过URL链接Django ContentType框架
-
24-10-2019 - |
题
我有调查表应用程序,可以动态创建表单。在我当前的系统中,我将其链接到项目。这是我的模型的示例。我想将问卷应用程序与当前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)
在我的问卷中,视图,在此示例中,我有两个基本函数Quartion_Set创建和问题创建。在Question_Set创建函数中,我有一个表单,该表单允许我将创建的问题添加到Question_Set,然后保存Question_Set。目前,我还将URL中的Project_ID传递给此视图,因此我可以获取项目实例并添加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"),
我相信解决方案涉及django 内容类型 框架,但我不确定通过URL传递模型类的最佳方法。因此,如果要将Question_Set保存到FOO模型而不是项目。在URL中,我将如何识别模型类?
解决方案
我认为问题可能是您组织模型的方式。我还会避免使用模型名称以结尾 _set
因为那可能会变得非常混乱。那又如何呢:
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()
一旦将问卷明确定义为自己的完整模型,创建URL就会变得更加简单:
#questionnaire.urls
#pattern for question_set_create
url(r'^(?P<content_type>[-\w]+)/(?P<object_id>[-\w]+)/add_set/$', 'questionnaire_create' , name="questionnaire_create"),
其中content_type是内容类型的名称(例如'projects.project'或类似内容),而object_id是匹配记录的主要键。
因此,为项目ID创建问卷的等效URL将是 /questionnaires/projects.project/1/add_set/
不隶属于 StackOverflow