为特定对象的模型关系添加例外

时间:2018-03-18 11:20:23

标签: python django django-models django-views

我是django和python的新手。在我的应用程序中,为每个用户分配了许多项目,但每个项目都有一个特定用我想要实现的是向用户展示从未创建任何项目,项目演示。

我尝试过,当用户注册时,他被直接分配了演示项目,但是因为一个项目只有一个用户在另一个用户登录时无效。

是否可以为模型属性创建例外,以指定特定项目可以拥有多个用户?

这是我的代码: 项目模型:

class Project(models.Model):

    name = models.CharField(max_length=250)
    team_id = models.ForeignKey(Team, blank=True, null=True)
    project_hr_admin = models.ForeignKey('registration.MyUser', blank=True, null=True)
    candidat_answers = models.ManyToManyField('survey.response')
    applicant = models.ManyToManyField(MyUser, related_name="applicant")
    created_at = models.DateTimeField(auto_now_add=True)

    def get_absolute_url(self):
        return reverse('website:ProjectDetails', kwargs={'pk1': self.pk})

注册用户:

def registerManager(request):
    #import pdb; pdb.set_trace()
    registered = False
    if request.method == "POST":
        Manager_form = ManagerForm(data=request.POST)

        if Manager_form.is_valid():
            user = Manager_form.save()
            user.set_password(user.password)
            user.is_manager = True
            user.save()
            registered = True
            login(request, user)
            demoProject = Project.objects.get(name="Project SoftScores")
            request.user.project_set.add(demoProject)
            return HttpResponseRedirect(reverse('website:hr_index'))
        else:
            print("Error!")
    else:
        Manager_form = ManagerForm()
    return render(request, 'HR_registration_form.html',
                  {'Manager_form': Manager_form,
                   'registered': registered})

错误讯息: SystemCheckError:系统检查发现了一些问题:

错误:

website.DemoProject.applicant: (fields.E304) Reverse accessor for 'DemoProject.applicant' clashes with reverse ac
cessor for 'Project.applicant'.
        HINT: Add or change a related_name argument to the definition for 'DemoProject.applicant' or 'Project.app
licant'.
website.DemoProject.applicant: (fields.E305) Reverse query name for 'DemoProject.applicant' clashes with reverse
query name for 'Project.applicant'.
        HINT: Add or change a related_name argument to the definition for 'DemoProject.applicant' or 'Project.app
licant'.
website.Project.applicant: (fields.E304) Reverse accessor for 'Project.applicant' clashes with reverse accessor f
or 'DemoProject.applicant'.
        HINT: Add or change a related_name argument to the definition for 'Project.applicant' or 'DemoProject.app
licant'.
website.Project.applicant: (fields.E305) Reverse query name for 'Project.applicant' clashes with reverse query na
me for 'DemoProject.applicant'.
        HINT: Add or change a related_name argument to the definition for 'Project.applicant' or 'DemoProject.app
licant'.

WARNINGS:
website.DemoProject.project_hr_admin: (fields.W340) null has no effect on ManyToManyField.

编辑代码:

class BaseProject(models.Model):
    name = models.CharField(max_length=250)
    team_id = models.ForeignKey(Team, blank=True, null=True)
    project_hr_admin = models.ForeignKey('registration.MyUser', blank=True, null=True)
    candidat_answers = models.ManyToManyField('survey.response')
    applicant = models.ManyToManyField(MyUser, related_name="applicant")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True

    def get_absolute_url(self):
        return reverse('website:ProjectDetails', kwargs={'pk1': self.pk})

    def __str__(self):
        return self.name


class Project(BaseProject):
    def has_member_responses(self, result=None):
        try:
            x = Project.objects.get(id=self.id).team_id.members.all()

            for i in x:
                result = 1
                if i.response_set.exists():
                    result = result * True
                else:
                    result = result * False
            return result
        except AttributeError:
            return False


class DemoProject(BaseProject):
    project_hr_admin = models.ManyToManyField('registration.MyUser', blank=True, null=True)

1 个答案:

答案 0 :(得分:2)

有几种方法可以解决这个问题,但最干净的我认为是创建一个抽象的BaseProject模型并使其成为Project模型的父类和DemoProject模型。

class BaseProject(models.Model):
    name = models.CharField(max_length=250)
    team_id = models.ForeignKey(Team, blank=True, null=True)
    project_hr_admin = models.ForeignKey('registration.MyUser', blank=True, null=True)
    candidat_answers = models.ManyToManyField('survey.response')
    applicant = models.ManyToManyField(MyUser, related_name="applicant")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True

    def get_absolute_url(self):
        return reverse('website:ProjectDetails', kwargs={'pk1': self.pk})

现在将DemoProject创建为BaseProject

的孩子
class DemoProject(BaseProject):

    project_hr_admin = models.ManyToManyField('registration.MyUser', blank=True, null=True)

然后您可以更新注册码以使用新模型。

def registerManager(request):
    registered = False
    if request.method == "POST":
        Manager_form = ManagerForm(data=request.POST)

        if Manager_form.is_valid():
            user = Manager_form.save()
            user.set_password(user.password)
            user.is_manager = True
            user.save()
            registered = True
            login(request, user)
            demo_project = DemoProject.objects.get(name="Demo Project")
            request.user.project_set.add(demoProject)
            return HttpResponseRedirect(reverse('website:hr_index'))
        else:
            print("Error!")
    else:
        Manager_form = ManagerForm()
    return render(request, 'HR_registration_form.html',
              {'Manager_form': Manager_form,
               'registered': registered})

通过这种方式,您已将两个实体分开,并设法保留DemoProject的行为/身份(A DemoProject仍为Project)。

这也意味着您可以修改主Project模型,而不会影响DemoProject模型。

您的主Project模型现在应该如下所示

class Project(BaseProject):
     # any custom stuff that's unique to a project
    pass