2017-11-13 273 views
5

İki modelim var Kategori ve Ürünler.ManyToMany alanı için bir Widget'ı kendi başına dairesel bir ForeignKey olan bir Modele özelleştirme

  • Ürün birden Ürünleri olabilir çoklu Kategoriler
  • bir Kategori sahip olabilir.
  • Kategoriler, kendilerine ait bir dairesel Yabancı anahtara sahiptir.
  • tüm Kategoriler aynı derinlik seviye var

Örnek:

  • Kategori A
    • Kategori A_1
    • kategori A_2
      • Kategori A_2_1
  • Kategori B
  • Kategori C
    • Kategori C_1

models.py

class Product: 
    categories = models.ManyToManyField(Category) 
    name = models.CharField(max_length=255) 

class Category: 
    categories = models.ForeignKey(self) 
    name = models.CharField(max_length=255) 

olarak Form I bir ModelForm kullanın:

ben Ürün Formu oluşturma günü şartlı seçme (dar seçenekleri) uygulamak istiyoruz:

  1. elde etmek istiyorum ne

    class ProductForm(ModelForm): 
        class Meta: 
         model = Product 
         fields = ['categories', 'name', 'short_description', 'description'] 
         widgets = { 
          'categories': MyWidget, 
         } 
    

    Yalnızca üst üst Kategoriler (seviye 0 A, B, C) kullanılabilir

  2. Kullanıcı bir üst Kategori seçer. Ebeveynin çocukları varsa yeni bir Seçme kutusu çocuklarıyla (kategori düzeyi 1 A1, C1) görünürse (kategori seviyesi 1 A1, C1)

    Kullanıcı bir seviye 1 Kategori (A1, C1) seçin.ebeveyn çocuk varsa yeni Seç kutusu bir kullanıcı ağacındaki "en küçük" kategorisini seçin, çocuğu yok (özyinelemeli) availavable kadar işlem tekrarlanır

    • çocuklarına (düzey 2 A2) ile görünür
    • kullanıcı daha fazla kategori ekleyin ve seçme yapmak istiyorum tekrar
    • 1-3 işlemini başlatmak için
    • yeni düğme, Form üzerinde JavaScript
    • kullanarak seçmek yeni eklemek Ben sadece son çocuk göndermek istediğiniz Gönder kullanılabilir kategoriler

Seçenekler düşündüm:

  1. Değişim ManyToMany coresponding varsayılan Alanları - görünüyor hiç iyi kancaları ve/veya miras
  2. var gibi kullanın ManytoMany olmayan bir varsayılan özel Saha instean (Charfield gibi) - Temizlemede daha karmaşık, kaydetme
  3. Widget'ı değiştir/devral.

    1. : My sorunlar ı her biri için değerlerle, 7 Seç Kutular var diyelim, teslim varsayılan Field veri göndermek ve almak/

    Pratik düzenleme üzerinde göstermek için nasıl Parent1-> Child11-> Child111

  4. Parent2-> Child21
  5. Parent3-> Child31-> Child311 ben göndermek için (diğer verilerle birlikte) teslim tarayıcı üzerinde Django söylemek nasıl

ManyToMany her üç çocukta da son Çocuk

Onları Javascript ile toplayabilirim, ama Django'ya bu bilgiyi almam gerektiğini söylemeliyim, ihtiyacın olan şey bu.

kod ve bunun nasıl göstergesi olarak yardıma ihtiyacım var.

enter image description here

+0

HTML şablonu neye benziyor? İfadeler gibi herhangi bir mantık sağladınız mı? Bence çözümünüzün bulunduğu yer burası .. – johnashu

+0

HTML şablonunun önemi yok, konu ebeveynler ve çocuklar arasındaki ilişki ile ilgili ihtiyaç duyduğum bilgiler ve kategorinin derinlik seviyesi şablona gönderilmiyor . ManyToMany tarafından tahsis edilen varsayılan Alanın üzerine yazmam gerekiyor. Ben 'iç' Field ModelSelectMultiple atıftayorum – user3541631

cevap

2

Django bunun yerine modelini ithal etmek zorunda ve doğrudan atamadan bir '<app_name>.<model_name>' dizesi olarak ForeignKey veya ManyToManyField bir de başvuran modelini tanımlamanızı sağlar. Bu, başta dairesel ithalat olmak üzere birçok sorunu çözmektedir.


bu, bir Product modeliyle bir Category model ve products olan uygulamaları categories var varsayarsak:

products/models.py:

class Product: 
    categories = models.ManyToManyField(Category) 
    name = models.CharField(max_length=255) 

categories/models.py:

class Category: 
    categories = models.ManyToManyField(self) 
    name = models.CharField(max_length=255) 

doğrudan neye ihtiyacınız için çevirebilir:

products/models.py:

class Product: 
    categories = models.ManyToManyField('categories.Category') 
    name = models.CharField(max_length=255) 

categories/models.py: Bununla

class Category: 
    categories = models.ManyToManyField('self') 
    name = models.CharField(max_length=255) 

, istediğiniz kadar kategori olabilir:

category_one = Category.create(name='Category one') 
category_two = Category.create(name='Category two') 
category_three = Category.create(name='Category three') 
category_three.categories.add(category_one, category_two) 
some_product = Product.create(name='Test Product') 
some_product.categories.add(category_three) 

(ManyToManyField docs)


Ayrıca, herhangi bir Python sınıfı ile, self'un sınıfın kendisi olmadığını da unutmayın - bu örnek. Yani, bir örnek yönteminin dışında referans yapamazsınız, neden here hakkında iyi bir açıklama var. 'self' dizesinin burada çalışmasının tek sebebi, Django'nun bunu sınıfın içine çevirmesi, categories.Category –– 'self''un categories.Category ile değiştirilmesi için iyi bir fikir olabilir.

+0

Ben Django yapıyor ne olduğunu anlıyorum, bu sorun değil, ManytoMany için Django tarafından seçilen varsayılan 'iç' Alan üzerine yazmak ve ayrıca özel bir widget oluşturmak gerekiyor – user3541631