2014-12-01 2 views
0

이 모델의 공급 업체에 서비스를 할당 할 수있는 양식을 만들고 싶습니다. 다른 프로그램에서 사용하는 DB를 사용하기 때문에 정의 된 M2M 관계가 없으므로 변경할 수없는 것 같습니다. 나는 그것도 틀릴지도 모른다.여러 개의 체크 박스가있는 양식과 양식을 사용하는 M2M

class Service(models.Model): 
    name = models.CharField(max_length=30L, blank=True) 


class ServiceUser(models.Model): 
    service = models.ForeignKey(Service, null=False, blank=False) 
    contact = models.ForeignKey(Contact, null=False, blank=False) 


class SupplierPrice(models.Model): 
    service_user = models.ForeignKey('ServiceUser') 
    price_type = models.IntegerField(choices=PRICE_TYPES) 
    price = models.DecimalField(max_digits=10, decimal_places=4) 

나는이 양식을 만든 : 뭔가 잘못이다

class SupplierServiceUpdateView(FormActionMixin, TemplateView): 

    def get_context_data(self, **kwargs): 
     supplier = Contact.objects.get(pk=self.kwargs.get('pk')) 
     service_user = ServiceUser.objects.filter(contact=supplier) 

     form = SupplierServiceForm(instance=service_user) 

     return {'form': form} 

나는 느낌이 :

여기
class SupplierServiceForm(ModelForm): 
    class Meta: 
     services = ModelMultipleChoiceField(queryset=Service.objects.all()) 
     model = ServiceUser 

     widgets = { 
      'service': CheckboxSelectMultiple(), 
      'contact': HiddenInput(), 
     } 

내가 어떤 성공없이 작동하기 시작보기입니다 내가 그것을하려고하는 방법. 올바른 양식이 표시되었지만 컨택으로 인스턴스화되지 않고 공급자가 이미 service_user에 일부 항목이 있어도 확인란이 선택되어 있지 않습니다.

답변

0

내 문제의 해결책은 실제로 through 인수를 사용하여 누락 된 m2m 관계를 통합하기 위해 내 모델을 재정의했습니다. 그런 다음 특별한 init 메서드를 사용하여 폼을 선택 상자에 표시하고 save() 메서드를 사용하여 m2m 관계를 사용하여 폼을 저장해야했습니다.

class Supplier(Contact): 
    services = models.ManyToManyField('Service', through='SupplierPrice') 


class Service(models.Model): 
    name = models.CharField(max_length=30L, blank=True) 


class ServiceUser(models.Model): 
    service = models.ForeignKey(Service, null=False, blank=False) 
    supplier = models.ForeignKey(Supplier, null=False, blank=False) 
    price = models.Decimal(max_digits=10, decimal_places=2, default=0) 

그리고 형식, 토핑 및 피자 재료에 대한 매우 유명한 게시물에서 적응.

class SupplierServiceForm(ModelForm): 

    class Meta: 
     model = Supplier 
     fields = ('services',) 

     widgets = { 
      'services': CheckboxSelectMultiple(), 
      'contact_ptr_id': HiddenInput(), 
      } 

     services = ModelMultipleChoiceField(queryset=Service.objects.all(), required=False) 

    def __init__(self, *args, **kwargs): 
     # Here kwargs should contain an instance of Supplier 
     if 'instance' in kwargs: 
      # We get the 'initial' keyword argument or initialize it 
      # as a dict if it didn't exist. 
      initial = kwargs.setdefault('initial', {}) 
      # The widget for a ModelMultipleChoiceField expects 
      # a list of primary key for the selected data (checked boxes). 
      initial['services'] = [s.pk for s in kwargs['instance'].services.all()] 

     ModelForm.__init__(self, *args, **kwargs) 


    def save(self, commit=True): 
     supplier = ModelForm.save(self, False) 
     # Prepare a 'save_m2m' method for the form, 

     def save_m2m(): 
      new_services = self.cleaned_data['services'] 
      old_services = supplier.services.all() 

      for service in old_services: 
       if service not in new_services: 
        service.delete() 

      for service in new_services: 
       if service not in old_services: 
        SupplierPrice.objects.create(supplier=supplier, service=service) 
     self.save_m2m = save_m2m 

     # Do we need to save all changes now? 
     if commit: 
      self.save_m2m() 

     return supplier 

이렇게하면 첫 번째 모델이 변경되어 기존 DB에 엉망이되지만 적어도 작동합니다.

0

메타 클래스에서 서비스를 정의하고 있습니다. SupplierServiceForm 시작 직후에 외부에 두십시오. 적어도 그것은 그때 나타나야합니다.

편집 :

오해했습니다. 1 개의 값만 가질 수있는 필드에 대해 다중 선택을 표시하려는 것 같습니다. 서비스 필드는 여러 서비스를 저장할 수 없습니다. 정의에 따르면 ServiceUser는 하나의 서비스 만 가질 수 있습니다. 데이터베이스를 사용하는 다른 응용 프로그램으로 인해 데이터베이스를 수정하지 않으려는 경우 Service에 대한 many to many 관계로 다른 필드를 만들 수 있습니다. 이전 필드를 사용하여 앱의 다른 부분과 충돌을 일으킬 수 있지만 다른 방식으로는 보이지 않는 관계를 수정하지 않아도됩니다.

+0

서비스가 포함 된 확인란 목록을 새로운 여러 필드로 표시합니다. 내가 service_user라는 쿼리로 인스턴스화하려고하면 쿼리 세트에 아무런 속성이 없다는 것에 불평합니다. __meta__ 어쨌든 multiplechoice 필드는 필요 없지만 확인란은 필요하지 않습니다. –

+0

service_user = models.ManyToManyField (ServiceUser) 또는 service_user = models.ManyToManyField (Service)와 같이 정의하여 처리 할 수 ​​있음을 의미합니까? 데이터를 파괴하지 않으면 시도 할 수 있습니다. –

+0

원래 필드와 관련없는 새로운 필드입니다. 앞서 언급했듯이이 문제는 응용 프로그램의 이전 부분에서 해당 필드에 추가하는 항목에 액세스 할 수 없다는 유일한 문제가 있습니다. – cdvv7788

관련 문제