我有一个链接模型:
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})
my 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())
my 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 :(得分:0)
我相信您正在使用AutoSlugField
中的django-autoslug,而您试图通过非唯一字段获取。默认情况下,AutoSlugField
不会使您的字段唯一,来自docs:
AutoSlugField还可以在保存时执行以下任务:
- 从另一个字段填充自己(使用populate_from),
- 使用自定义slugify功能(使用slugify或设置)和
- 保留值的唯一性(使用unique或unique_with)。
这些任务都不是强制性的,即您可以拥有自动填充的非唯一字段,手动输入的唯一字段(绝对唯一或在给定日期内)或两者都有。
快速修复slug = AutoSlugField(populate_from='child_name', unique=True)
更新(自您发布了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 unique=True
。