Django - 将数据插入具有唯一约束的多对多关系模型

时间:2013-10-08 00:08:02

标签: django django-models django-views

我有一个models.py:

class Skill(models.Model):
    title = models.CharField(max_length=255, unique=True)
    category = models.ForeignKey(
        SkillCategory, default=None, null=True, blank=True
    )

    def __unicode__(self):
        return self.title


class UserProfile(models.Model):
    user = models.OneToOneField(User)
    skill = models.ManyToManyField(Skill)

    def __unicode__(self):
        return self.user.username

在我的观点中,我基本上获得了一组技能,用于在登录后填充UserProfileSkills模型:

@login_required
def UpdateUserSkills(request):
    cleaned_skills = get_skill_list(user=request.user)

    user_profile, created = UserProfile.objects.get_or_create(
        user=request.user
    )

    for s in cleaned_skills:
        user_profile.skill.get_or_create(title=s)

    return HttpResponseRedirect(reverse('show_user_profile')) 

我的问题是 - 这种添加技能的方法是否尊重模型的唯一约束,如果确实如此,如果已经存在,它是否会为给定用户填充这些技能?做这样的事情可能会更好:

for s in cleaned_skills:
    skill = Skill.objects.get_or_create(title=s)
    user_profile.skill.get_or_create(title=skill)

虽然这看起来好像会产生两倍的数据库查询。

也许还有另一种更好的方式?

1 个答案:

答案 0 :(得分:1)

你应该这样做:

for s in cleaned_skills:
    skill = Skill.objects.get_or_create(title=s)
    user_profile.skill.add(skill)

只有具有相同标题的技能尚不存在时,才会创建技能。然后它将技能添加到用户。

编辑:如果您执行bulk_create,则可以保存一些查询。像这样:

skill_titles = Skill.objects.values_list('title', flat=True)
new_skills = Skill.objects.bulk_create([Skill(title=s) for s in cleaned_skills if s not in skill_titles])
user_profile.skill.add(*new_skills)