2014-11-27 3 views
0
class PersonSite(models.Model): 
    vps_id    = models.AutoField(primary_key=True) 
    person    = models.ForeignKey(CanonPerson, db_column='p_id',null=True) 
    site    = models.ForeignKey(CanonSite, db_column='s_id',null=True) 

person_sites = PersonSite.objects.filter(person=cp) 
for person_site in person_sites: 
    if person_site and person_site.site_id and person_site.site.s_id: 
     # crashes for some records 

데이터에 문제가 있습니다. PersonSite은 더 이상 존재하지 않는 site을 가리킬 수 있습니다. 디버거에서 내가 그러나 해당 ID가 데이터베이스에 존재하지 않는, person_site.site_id는 5579의 값을 갖는 것을 볼 수 있습니다더 이상 존재하지 않는 ForeignKey를 확인하는 방법은 무엇입니까?

select * from tbl_vpd_sites where s_id = 5579 

따라서 person_site.site_id가 null는 아니고, 아직 단지 조건 내에서 person_site.site에 액세스하는 응용 프로그램과 충돌 메시지 :

DoesNotExist: CanonSite matching query does not exist. 

이것은 매우 어려운 상황입니다.이 경우를 무시하고 확인할 수조차 없습니다.

+0

'person_site.site.s_id'를'CanonSite.objects.filter (pk = s_id) .count()'로 바꾸는 것은 어떨까요? – allcaps

+0

그러면 루프의 각 반복마다 데이터베이스를 호출하게됩니다. 아마 예외를 잡는 더 좋은 방법이있을 것입니다. 이것은 내가 지금 노력하고있는 것입니다. – Houman

+0

예. '.count()'는 오래된 것이므로'.exists()'를 사용해야합니다. – allcaps

답변

1

PersonSite.site는 null=True이므로 액세스하기 전에 개체가 있는지 확인해야합니다.

대신 이러한 모든 검사를 수행하는 대신 if person_site and person_site.site_id and person_site.site.s_id:을 사용하면 db를 쿼리하고 빈 사이트를 필터링 할 수 있습니다.

person_sites = PersonSite.objects.filter(person=cp).filter(site__isnull=False) 

이렇게하면 IS NOT NULL 사이트의 PersonSite 객체 만 반환되므로 pk가 반환됩니다.

+0

네, 이것은 좋은 해결책입니다. – Houman

관련 문제