2011-11-04 1 views
2

이상한 요구가있어서 고객이 데이터베이스 지원을 위해 webapp를 구현할 것을 요청했습니다. 내가 장고를 사랑하기 때문에 그것을 사용하기로 결정했다.사용자에게 SQL 제약 조건을 추가 할 수있는 권한 부여 Django

필자는 다음과 같이 어려운 점이 있습니다 : 사용자가 Python에 대해 모른 채 IntegerField의 범위를 확인하는 것과 같은 모델 제약 조건을 작성하는 데 "강력한"힘을 가져야합니다.

그래서 몇 가지 아이디어가 있지만 올바른 것이 있으면 무엇이 있는지 잘 모르겠습니다. 여기에 내 생각이다 :

  1. 는 쓰기 (이 끔찍한 소리)
  2. 를 파이썬 스크립트와 models.py 파일을 작성하여 사용할 수있는 사용자 친화적 방법을 구현 일부 관리자
  3. 자바 스크립트
  4. 를 사용하여 템플릿 측 유효성 검사를 구현 원시 SQL CHECK 제약 조건을 사용하는 작업이지만 여전히 방법을 모르겠다.

이 요청을 해결할 수 있습니까? 가장 간단한 방법에 대해 알려 줄 수 있습니까? 사전에

감사합니다,

- 플라 비오

+0

문제를 해결하려면 javascript를 사용하지 않는 것이 좋습니다. Perfomance-wise는 적어도 쿼리 세트에 수백 또는 수천 개의 항목이 남을 것으로 예상되는 경우 끔찍한 생각입니다. –

답변

1

네, 실제로 가능하다. 문제를 해결하기 위해 custom object managerdynamic Q objects을 사용합니다. 여기에 예제가 있습니다.

  1. 제약 조건에 대한 정보를 저장할 적절한 모델을 만듭니다. 제약 조건을 특정 모델 클래스에 연결하기 위해 ForeginKey를 ContentType으로 만듭니다.

    #your_app/models.py 
    from django.contrib.contenttypes.models import ContentType 
    from django.contrib.auth.models import User 
    
    class PerUserConstraint(models.Model): 
        user = models.ForeignKey(User) 
        content_type = models.ForeignKey(ContentType) 
        field_name = models.CharField(max_length = 255) 
        predicate = models.CharField(max_length = 255) #for example, 'contains' etc. 
        filter_value = models.CharField(max_length = 255) 
    
  2. 사용자 정의 관리자를 생성하여 모델에 등록하십시오. 나는이 코드를 테스트하지 않았다 YourModel.c.get_constrainted_query(user)

    참고,하지만 난 당신이 개념을 파악했습니다 희망 :

    #your_app/models.py 
    from django.db.models.query_utils import Q 
    
    class ConstraintedManager(models.Manager): 
        def get_constrainted_query(self, user): 
         qs = self.model.objects.all() 
         content_type = ContentType.objects.get_for_model(self.model.__class__) 
         constraints = PerUserConstraint.objects.filter(
                   user = user, 
                   content_type = content_type 
         ) 
         if constraints: 
          filters = [] 
          for constraint in constraints: 
           filters.append(('%s__%s' % (constraint.field_name, constraint.predicate), constraint.value) 
          # at this point filters should look like this: 
          # [('question__contains', 'dinner'), ('question__contains', 'meal')] 
          q_list = [Q(x) for x in filters] 
          return qs.filter(reduce(operator.and_, q_list)) 
          # which is something like 
          # return qs.filter(Q(question__contains = 'dinner') & Q(question__contains = 'meal')) 
    
         else: 
          return qs  
    
    class YourModel(models.Model): 
        #some fields 
        ... 
        c = ConstraintedManager() 
    

그래서 귀하의 의견에이처럼 사용할 수 있습니다.

ModelAdmin에서 쿼리를 무시하려면 thisthis 기술을 사용하십시오.

+1

이것은 매우 흥미 롭습니다, 도와 주셔서 대단히 감사합니다. –

+0

여러분을 환영합니다! :)))) –