通过URL链接Django ContentType框架

时间:2011-01-25 00:45:04

标签: django contenttype

我有问卷调查应用程序,允许动态创建表单。在我当前的系统中,我将它链接到一个项目。这是我的模型的一个例子。我想将问卷调查应用程序与我当前的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)

在我的问卷调查中,对于这个例子,我有两个基本功能Question_set create和Question create。在Question_set创建函数中,我有一个表单,允许我将创建的问题添加到Question_set,然后保存Question_set。目前我还将url中的project_id传递给此视图,以便我可以获取Project实例并添加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 ContentType框架,但我不确定通过url传递模型类的最佳方法。因此,如果要将Question_set保存到Foo模型而不是Project。如何在网址中识别模型类?

1 个答案:

答案 0 :(得分:0)

我认为问题可能在于您组织模型的方式。我也会避免使用以_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#1创建调查问卷的等效URL将为/questionnaires/projects.project/1/add_set/