复制/克隆Django模型

时间:2018-01-07 23:21:17

标签: python django python-3.x django-models

我正在尝试制作此模型的副本

class Quiz(models.Model):

title = models.CharField(
    verbose_name=_("Title"),
    max_length=60, blank=False)

description = models.TextField(
    verbose_name=_("Description"),
    blank=True, help_text=_("a description of the quiz"))

url = models.SlugField(
    max_length=60, blank=False,
    help_text=_("a user friendly url"),
    verbose_name=_("user friendly url"))

category = models.ForeignKey(
    Category, null=True, blank=True,
    verbose_name=_("Category"))

random_order = models.BooleanField(
    blank=False, default=False,
    verbose_name=_("Random Order"),
    help_text=_("Display the questions in "
                "a random order or as they "
                "are set?"))

max_questions = models.PositiveIntegerField(
    blank=True, null=True, verbose_name=_("Max Questions"),
    help_text=_("Number of questions to be answered on each attempt."))

answers_at_end = models.BooleanField(
    blank=False, default=False,
    help_text=_("Correct answer is NOT shown after question."
                " Answers displayed at the end."),
    verbose_name=_("Answers at end"))

exam_paper = models.BooleanField(
    blank=False, default=False,
    help_text=_("If yes, the result of each"
                " attempt by a user will be"
                " stored. Necessary for marking."),
    verbose_name=_("Exam Paper"))

single_attempt = models.BooleanField(
    blank=False, default=False,
    help_text=_("If yes, only one attempt by"
                " a user will be permitted."
                " Non users cannot sit this exam."),
    verbose_name=_("Single Attempt"))

pass_mark = models.SmallIntegerField(
    blank=True, default=0,
    verbose_name=_("Pass Mark"),
    help_text=_("Percentage required to pass exam."),
    validators=[MaxValueValidator(100)])

success_text = models.TextField(
    blank=True, help_text=_("Displayed if user passes."),
    verbose_name=_("Success Text"))

fail_text = models.TextField(
    verbose_name=_("Fail Text"),
    blank=True, help_text=_("Displayed if user fails."))

draft = models.BooleanField(
    blank=True, default=False,
    verbose_name=_("Draft"),
    help_text=_("If yes, the quiz is not displayed"
                " in the quiz list and can only be"
                " taken by users who can edit"
                " quizzes."))

基本上这是一个测验。它有自己的问题,可以在django管理员中添加。现在当我复制这个模型时,副本的问题就不存在了。

我使用此功能制作副本。

Obj=Quiz.objects.get(pk=pkofquiziwanttocopy)
Obj.pk=None
Obj.save()

这是测验的副本,但问题不在那里。现在,admin.py中有一些关于测验的qurstions的代码。这可能会有所帮助。

class QuizAdminForm(forms.ModelForm):
"""
below is from
https://stackoverflow.com/questions/11657682/
django-admin-interface-using-horizontal-filter-with-
inline-manytomany-field
"""

class Meta:
    model = Quiz
    exclude = []

questions = forms.ModelMultipleChoiceField(
    queryset=Question.objects.all().select_subclasses(),
    required=False,
    label=_("Questions"),
    widget=FilteredSelectMultiple(
        verbose_name=_("Questions"),
        is_stacked=False))

def __init__(self, *args, **kwargs):
    super(QuizAdminForm, self).__init__(*args, **kwargs)
    if self.instance.pk:
        self.fields['questions'].initial =\
            self.instance.question_set.all().select_subclasses()

def save(self, commit=True):
    quiz = super(QuizAdminForm, self).save(commit=False)
    quiz.save()
    quiz.question_set = self.cleaned_data['questions']
    self.save_m2m()
    return quiz

如何使用原始问题制作此模型的副本?

2 个答案:

答案 0 :(得分:0)

假设Question模型有Quiz的外键,你可以像克隆测验那样克隆问题:

quiz = Quiz.objects.get(pk=pkofquiziwanttocopy)
quiz.pk = None
quiz.save()
old_quiz = Quiz.objects.get(pk=pkofquiziwanttocopy)
for quest in old_quiz.question_set.all():
    quest.pk = None
    quest.quiz = quiz
    quest.save()

答案 1 :(得分:0)

最终成为解决方案的是:

quiz = Quiz.objects.get(pk=pkofquiziwanttocopy)
quiz.pk = None
quiz.save()
old_quiz = Quiz.objects.get(pk=pkofquiziwanttocopy)

quiz.question_set=old_quiz.question_set.all()