2016-11-07 76 views
0

我有一個鏈接模型:get()返回多個Children - 它返回2!在Django

class Children(models.Model): 
    person = models.ForeignKey(Person, on_delete=models.CASCADE) 
    child_name = models.CharField(max_length=150, null=True, blank=True) 
    slug = AutoSlugField(populate_from='child_name') 
    blood_group = models.CharField(max_length=5, blank=True) 

    class Meta: 
      unique_together = ('slug', 'person') 

def get_absolute_url(self): 
    return self.person.get_absolute_url() 

def get_delete_url(self): 
    return reverse(
     'member:children-delete', 
     kwargs={ 
      'person_slug': self.person.slug, 
      'children_slug': self.slug}) 

def get_update_url(self): 
    return reverse(
     'member:children-update', 
     kwargs={ 
      'person_slug': self.person.slug, 
      'children_slug': self.slug}) 

我forms.py:

class ChildrenForm(SlugCleanMixin, forms.ModelForm): 

    class Meta: 
     model = Children 
     exclude = ('person',) 

    def clean(self): 
     cleaned_data = super().clean() 
     slug = cleaned_data.get('slug') 
     person_obj = self.data.get('person') 
     exists = (
      Children.objects.filter(
       slug__iexact=slug, 
       person=person_obj, 
      ).exists()) 
     if exists: 
      raise ValidationError(
       "Children with this Slug " 
       "and Person already exists.") 
     else: 
      return cleaned_data 

    def save(self, **kwargs): 
     instance = super().save(commit=False) 
     instance.person = (
      self.data.get('person')) 
     instance.save() 
     self.save_m2m() 
     return instance 

views.py:

class ChildrenCreate(ChildrenFormMixin, ChildrenGetObjectMixin, 
    PersonContextMixin,CreateView): 
    template_name = 'member/children_form.html' 
    model = Children 
    form_class = ChildrenForm 


class ChildrenUpdate(ChildrenFormMixin, ChildrenGetObjectMixin, 
    PersonContextMixin,UpdateView): 
    template_name = 'member/children_form.html' 
    model = Children 
    form_class = ChildrenForm 
    slug_url_kwarg = 'children_slug'   



class ChildrenDelete(ChildrenFormMixin,ChildrenGetObjectMixin, 
    PersonContextMixin,DeleteView): 
    model = Children 
    slug_url_kwarg = 'children_slug' 

    def get_success_url(self): 
     return (self.object.person 
       .get_absolute_url()) 

我utils.py:

class ChildrenFormMixin(): 

    def get_form_kwargs(self): 
     kwargs = super().get_form_kwargs() 
     if self.request.method in ('POST', 'PUT'): 
      self.person = get_object_or_404(
       Person, 
       slug__iexact=self.kwargs.get(
        self.person_slug_url_kwarg)) 
      data = kwargs['data'].copy() 
      data.update({'person': self.person}) 
      kwargs['data'] = data 
     return kwargs 

class ChildrenGetObjectMixin(): 

    def get_object(self, queryset=None): 
     person_slug = self.kwargs.get(
      self.person_slug_url_kwarg) 
     children_slug = self.kwargs.get(
      self.slug_url_kwarg) 
     return get_object_or_404(
      Children, 
      slug__iexact=children_slug, 
      person__slug__iexact=person_slug) 

class PersonContextMixin(): 
    person_slug_url_kwarg = 'person_slug' 
    person_context_object_name = 'person' 

    def get_context_data(self, **kwargs): 

     person_slug = self.kwargs.get(
      self.person_slug_url_kwarg) 
     person = get_object_or_404(
      Person, slug__iexact=person_slug) 
     context = { 
      self.person_context_object_name: 
       person, 
     } 
     context.update(kwargs) 
     return super().get_context_data(**context) 

兒童創意爲同一父母的同一名字定了一個以上。當我試圖編輯孩子時,它給出"get() returned more than one Children -- it returned 2!"錯誤。在回溯中,它表示,'person__slug__iexact=person_slug'是此追溯的直接原因。

在表格中,我添加了乾淨的方法來捕捉錯誤並保持同一父母的孩子姓名的唯一性,但它不起作用。如果我做錯了,我能得到建議嗎?

編輯:

我一個人的模型:

class Person(models.Model): 
    name = models.CharField(max_length=250) 
    slug = AutoSlugField(populate_from='name') 
    birth_date = models.DateField(null=True, blank=True) 
    blood_group = models.CharField(max_length=5) 
    present_address = models.CharField(max_length=250, blank=True) 
    permanent_address = models.CharField(max_length=250, blank=True) 
    user = models.OneToOneField(
     settings.AUTH_USER_MODEL, 
     related_name='member_persons') 

    class Meta: 
     ordering = ['name'] 
     unique_together = ['name', 'birth_date'] 
+0

你想要發生什麼?你的搜索顯然比你想要的要多,但是應該發生什麼?錯誤?全部返回?一?你試過了什麼 – Sayse

+0

這意味着你的查詢獲得多個值,因爲這個查找不是唯一的。 –

+0

我想每個家長都有獨特的孩子。在我的模型中,我用unique_together =('slug','person')做了它 –

回答

0

我相信你正在使用AutoSlugFielddjango-autoslug,你試圖通過非唯一場得到。 AutoSlugField不會讓你的領域裏獨樹一幟默認情況下,從文檔:

AutoSlugField也可以對保存下列任務:

  • 填充自身,從另一個字段(使用populate_from)
  • 使用自定義slugify功能(使用slugify或設置),和
  • 保留值的唯一性(使用unique或unique_with)。

任何任務都不是強制性的,即您可以擁有自動填充的非唯一字段,手動輸入唯一字段(絕對唯一或在給定日期內)或兩者。

所以速戰速決是slug = AutoSlugField(populate_from='child_name', unique=True)

UPDATE(因爲你發佈你的Person模型)

的問題是相同的,解決方法是一樣的。

說明:

例如,你有兩個Person對象:

id name slug birth_date 
1 alex alex 10.10.2016 
2 alex alex 10.10.2015 

這不會違反unique_together = ['name', 'birth_date']

你有兩個Children對象:

id name slug person_id 
1 john john 1 
2 john john 2 

而且這不會違反unique_together = ('slug', 'person')既不

然後你正在查詢

get_object_or_404(
      Children, 
      slug__iexact='john', 
      person__slug__iexact='alex') 

這將匹配兩個對象。所以你有問題。快速解決方法是製作slu 012 unique=True

+0

我需要爲每個父級別唯一的子女姓名,並非所有的子女姓名都必須是唯一的。因此,如果我使用unique = True,它是否會爲父母和孩子的組合創造獨特的孩子? –

+0

@djpro我已經更新了答案。 –

+0

@vishe_shell,我在autoslug字段中使用unique = True,但它無法抵制創建重複的孩子 –