2013-10-08 60 views
0

我有一個models.py:Django的 - 將數據插入到多對多的關係模型,唯一約束

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 

在我的觀點我基本上得到了一套我用填充UserProfile技能和Skills車型登錄後:

@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

你應該做這樣的事情:

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) 
+0

謝謝你的一個很好的答案。兩種可行解決方案的額外標記。 Django調試工具欄實際上報告的查詢在同一時間完全相同。所以我會實施第一個解決方案,因爲它更清晰易讀。 –