2017-09-11 2 views
0

특정 제약 조건이 충족되지 않은 경우 장고 모델에서 저장을 방지하고 장고 직원이 알 수 있도록 유효성 검사 오류를 부여하고 싶습니다. 잘못됐다.django에 인스턴스를 저장하기 전에 여러 관계에서 count() 제약 조건을 확인하십시오.

through 매개 변수를 사용하여 지정된 중간 테이블의 제약 조건은 count()입니다.

models.py :

class Goal(models.Model): 
    name = models.CharField(max_length=128) 

class UserProfile(models.Model): 
    goals = models.ManyToManyField(Goal, through=UserProfileGoals, blank=True) 

class UserProfileGoal(models.Model): 
    goal = models.ForeignKey(Goals) 
    user_profile = models.ForeignKey(UserProfile) 

class UserGoalConstraint(models.Model): 
    user_profile = models.OneToOneField(UserProfile) 
    max_goals = models.PositiveIntegerField() 

는 그래서 UserGoalConstraint.max_goals 나에게 UserProfileGoal 모델에 저장됩니다 UserProfile.goal 정의 할 수있는 최대의 수를 제공합니다 (같은 UserGoalUserProfile에 더 자주 저장 될 수 있습니다)

저는 ModelForm의 clean(), 모델의 clean()pre_save 신호 이브를 사용하는 여러 게시물을 읽고 읽었습니다

class UserProfileGoal(models.Model): 
    goal = models.ForeignKey(Goals) 
    user_profile = models.ForeignKey(UserProfile) 

    def clean(self): 
    goal_counter = self.user_profile.goals.count() + 1 

    try: 
     qs = UserGoalConstraint.objects.get(user_profile=self.user_profile) 
    except UserGoalConstraint.DoesNotExist: 
     raise ObjectDoesNotExist('Goal Constraint does not exist') 

    if goal_counter > qs.max_goals: 
     raise ValidationError('There are more goals than allowed goals') 

정말 작동하지 않기 때문에 clean()도 갱신 할 수있는 국세청,

하지만 내가 가지고있는 실제 문제는, 어떻게, 그냥 업데이트 나 새 데이터베이스 항목 인 경우 어떻게 알 수 있습니까 +1은 ValidationError로 연결되는 잘못된 결과를 제공합니다.

직접 인라인을 통해 사용자 프로필에 목표를 추가 할 장고 - 관리자 인터페이스를 사용해야 제 의뢰인 :

admin.py : 그래서 그가 필요로

class UserProfileGoalInline(admin.TabularInline): 
    model=UserProfileGoal 

class UserProfileAdmin(admin.ModelAdmin) 
    ... 
    inlines = [UserProfileGoalInline, ] 

멋지게 통보 할 그는 사용자 프로필에 많은 목표를 추가합니다.

어쩌면 나는이 문제를 해결하는 방법에 대해 분명한 것을 놓치고있다. ...? 저는 어떻게 든 작동하는 사용자 친화적 인 솔루션을 찾고 있습니다 (= 관리 인터페이스에 정보를 얻으십시오).

[업데이트] : 나는 그러나 ... 그것이 clean()

if self.pk is not None: 
    return # it is not a create 
... 

의 시작 부분에 self.pk is None 트릭으로 생성되지 않았거나 어떠했는지 내가 그 문제를 다루는 것이라고 생각 확인 알고 시도 관리자 인라인에서 스태프 사용자가 둘 이상의 목표를 동시에 추가하면 clean()이이를 인식하지 못합니다.디버그 출력은 목표 카운터가 하나 더 있어야합니다 같은 숫자도 두 번째 항목을 보유하고 ModelFormclean 방법을 처리 할 수있는

답변

0

덕분에 시작 솔루션을 @zaidfazil합니다 :

class UserProfileGoalForm(forms.ModelForm): 
    class Meta: 
    model = UserProfileGoal 
    ... 

    def clean(self): 
    cleaned_data = super(UserProfileGoalForm, self).clean() 
    if self.instance.pk is not None: 
     return cleaned_data 
    user_profile = self.cleaned_data.get('user_profile') 
    goal_count = user_profile.goals.count() 
    goal_limit = UserGoalConstraint.objects.get(user_profile=user_profile).max_goals # removed try catch for get for easier reading 
    if goal_count >= goal_limit: 
     raise ValidationError('Maximum limit reached for goals') 
    return cleaned_data 

그러나, 이것은 사용자 프로필 관리 인터페이스에서 인라인을 처리하지 않습니다 clean() 당신이 추가 할 경우 제대로 처리하지 않습니다 하나 이상의 Goal을 동시에 누른 다음 저장을 누릅니다.

그래서 나는 인라인에 UserProfileGoalForm을 적용 max_num 정의 :

class UserProfileGoalInline(admin.TabularInline): 
    model=UserProfileGoal 
    form = UserProfileGoalForm 

    def get_max_num(self, request, obj=None, **kwargs): 
    if obj is None: 
     return 
    goal_limit = UserGoalConstraint.objects.get(training_profile=obj).max_goals 
    return goal_limit # which will overwrite the inline's max_num attribute 

지금 내 클라이언트 만 UserGoalConstraint에서 최대의 max_goals 값을 추가 할 수 있습니다, 또한 UserProfileGoal에 대한 가능한 관리 형태는 제약 조건을 처리합니다 :

class UserProfileGoalAdmin(admin.ModelAdmin): 
    form = UserProfileGoalForm 
0

유효성 검사 오류 줄 것을, 추가 2 개 목표에 보여줍니다

class GoalForm(forms.ModelForm): 
    class Meta: 
     model = Goal 
     ..... 

    def clean(self): 
     cleaned_data = super(GoalForm, self).clean() 
     if self.instance.pk is not None: 
      return cleaned_data 
     goal_limit = self.user_profile.usergoalconstraint.max_goals 
     goal_count = self.user_profile.goals.count() 
     if goal_count >= goal_limit: 
      raise ValidationError("Maximum limit reached for goals") 
     return cleaned_data 
+0

내 실제 사례에 대한 귀하의 제안을 시도했습니다. 하지만 이미'GoalForm' 클래스로 고민 중입니다. 'Goal'은'UserProfile'없이 만들 수 있습니다. 나는 당신이'UserProfileGoal'을 의미한다고 생각하니? 또한이 방법은 작동하지 않습니다. 질문의 UPDATE 섹션을 참조하십시오. 그러나'ModelForm'은 나에게 해결책을 주었고 나는 이것을 답으로 게시 할 것이다. – Dowi