2009-06-17 29 views
6

2 câu hỏi:Mô hình ràng buộc unique_together + Không = thất bại?

  • Làm cách nào để ngăn trùng lặp được tạo khi cha mẹ = Không và tên giống nhau?
  • Tôi có thể gọi phương thức mô hình từ bên trong biểu mẫu không?

Xin vui lòng xem đầy đủ chi tiết dưới đây:

models.py

class MyTest(models.Model): 
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children') 
    name = models.CharField(max_length=50) 
    slug = models.SlugField(max_length=255, blank=True, unique=True) 
    owner = models.ForeignKey(User, null=True) 

    class Meta: 
     unique_together = ("parent", "name") 

    def save(self, *args, **kwargs): 
     self.slug = self.make_slug() 
     super(MyTest, self).save(*args, **kwargs) 

    def make_slug(self): 
     # some stuff here 
     return generated_slug 

lưu ý: sên = độc đáo cũng!

forms.py

class MyTestForm(forms.ModelForm): 
    class Meta: 
     model = MyTest 
     exclude = ('slug',) 

    def clean_name(self): 
     name = self.cleaned_data.get("name") 
     parent = self.cleaned_data.get("parent") 

     if parent is None: 
      # this doesn't work when MODIFYING existing elements! 
      if len(MyTest.objects.filter(name = name, parent = None)) > 0: 
       raise forms.ValidationError("name not unique") 
     return name 

Chi tiết

Các unique_together contraint hoạt động hoàn hảo w/hình thức khi parent != None. Tuy nhiên khi parent == None (null) nó cho phép tạo bản sao.

Để thử và tránh điều này, tôi đã thử sử dụng biểu mẫu và định nghĩa clean_name để tìm cách kiểm tra trùng lặp. Điều này hoạt động khi tạo các đối tượng mới nhưng không hoạt động khi sửa đổi các đối tượng hiện có.

Ai đó đã đề cập đến tôi nên sử dụng commit = False trên tệp .Fave của ModelForm, nhưng tôi không thể tìm ra cách thực hiện/triển khai thực hiện điều này. Tôi cũng nghĩ về việc sử dụng has_changed của ModelForm để phát hiện các thay đổi đối với một mô hình và cho phép chúng, nhưng has_changed trả về true trên các đối tượng mới được tạo ra với biểu mẫu là tốt. Cứu giúp!

Ngoài ra, (phần nào là một câu hỏi hoàn toàn khác), tôi có thể truy cập phương thức mô hình make_slug() từ Biểu mẫu không? Tôi tin rằng hiện tại dòng exclude = ('slug',) của tôi cũng bỏ qua ràng buộc 'duy nhất' trên trường sên và trong trường lưu mô hình, tôi sẽ tạo con sên thay thế. Tôi đã tự hỏi nếu tôi có thể làm điều này trong forms.py thay thế?

+0

Xem http://stackoverflow.com/questions/3488264/django-unique- cùng-không-làm việc-với-ngoại-không cho một phương pháp cập nhật xử lý vấn đề này. Yêu cầu Django 1.2. –

Trả lời

-1

Tôi không biết chắc chắn điều này sẽ khắc phục được sự cố của bạn, nhưng tôi khuyên bạn nên thử nghiệm mã của bạn trên mã thân chính Django mới nhất. Nhận nó bằng:

svn co http://code.djangoproject.com/svn/django/trunk/ 

Đã có một vài sửa chữa cho unique_together kể từ khi phát hành 1.02, ví dụ: xem ticket 9493.

+0

im đã chạy thân cây – lostincode

-1

độc đáo cùng phải là một tuple của tuples

unique_together = (("parent", "name"),) 
+0

điều này không còn cần thiết – lostincode

0

Bạn có thể có một hình thức khác nhau cho dù bạn đang tạo hoặc cập nhật.

Sử dụng thể hiện kwarg khi tạo biểu mẫu.

if slug: 
    instance = MyTest.object.get(slug=slug) 
    form = MyUpdateTestForm(instance=instance) 
else: 
    form = MyTestForm() 

Đối với phần thứ hai, tôi nghĩ rằng đó là nơi bạn có thể mang lại cam kết = False, một cái gì đó như:

if form.is_valid(): 
    inst = form.save(commit=False) 
    inst.slug = inst.make_slug() 
    inst.save() 
Các vấn đề liên quan