【问题标题】:Add an exception for model relationship of a specific object为特定对象的模型关系添加例外
【发布时间】:2018-03-18 11:20:22
【问题描述】:

我是 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)

【问题讨论】:

  • 一个项目可以有多个用户。因此,您可能需要为此创建一个外键。看看这个例子:stackoverflow.com/questions/14663523/foreign-key-django-model
  • project_hr_admin = models.ForeignKey('registration.MyUser', blank=True, null=True) 不是相反的意思吗?一个用户可以有多个项目。 ?

标签: python django django-models django-views


【解决方案1】:

有几种方法可以处理这个问题,但我认为最简洁的方法是创建一个抽象的 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 的行为/身份(DemoProject 仍然是Project)。

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

您的主要Project 模型现在应该是这样的

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

【讨论】:

  • 是继承吗?
  • 是的,是继承。但在 Django 中有一个特别的地方。如果BaseProject 不是抽象模型,您将无法覆盖该字段,因此abstract = True 是必需的。
  • 我刚刚遇到一个大错误..我编辑了我的帖子..我有冲突...@danidee
  • 如果其他人需要,我使用了 '%(app_label)s' 和 '%(class)s ! Danidee 最佳答案 thx men!
猜你喜欢
  • 2018-12-03
  • 2018-01-15
  • 1970-01-01
  • 2010-10-28
  • 2011-10-22
  • 2018-07-30
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
相关资源
最近更新 更多