Связывание структуры Django ContentType через URL -адреса
-
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)
Внутри моего вопросника. Просмотр, для этого примера, есть две основные функции obster_set создать и создавать вопросы. В функции Вопроса_SET Создайте форму, у меня есть форма, которая позволяет мне добавлять созданные вопросы к вопросу, а затем сохранить obster_set. В настоящее время я также передаю Project_ID в URL -адресу этой точке зрения, чтобы я мог получить экземпляр проекта и добавить вопрос
#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"),
Я считаю, что решение включает в себя Джанго Тип содержимого Структура, но я не уверен, что лучший способ пройти класс модели через URL. Поэтому, если вопрос, который должен был быть сохранен в модели 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 является основным ключом соответствующей записи.
Таким образом, эквивалентный URL для создания вопросника для идентификатора проекта № 1 будет /questionnaires/projects.project/1/add_set/