2016-11-26 48 views
1

這是代碼:與get_object_or_404失敗的Django

>>> from shortener.models import KirrURL 
>>> from django.shortcuts import get_object_or_404 
>>> obj = get_object_or_404(KirrURL,shortcode='pric3e') 

Traceback (most recent call last):File"/Users/phil/Desktop/django110/lib/python3.5/site 
packages/django/shortcuts.py", line 85, in get_object_or_404 
return queryset.get(*args, **kwargs) 
File "/Users/phil/Desktop/django110/lib/python3.5/site-packages/django/db/models/query.py", line 385, in get 
self.model._meta.object_name 
shortener.models.DoesNotExist: KirrURL matching query does not exist. 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
File "<console>", line 1, in <module> 
File "/Users/phil/Desktop/django110/lib/python3.5/site-packages/django/shortcuts.py", line 93, in get_object_or_404 
raise Http404('No %s matches the given query.' %  queryset.model._meta.object_name) 
django.http.response.Http404: No KirrURL matches the given query. 

>>> obj = KirrURL.objects.get(shortcode='pric3e') 
>>> obj 
<KirrURL: http://google.com> 
>>> obj.id 
1 
>>> obj.url 
'http://google.com' 

我練的Django模型權now.The問題是,當我用get_object_or_404試圖得到某種方式匹配的第二個關鍵詞參數是該數據失敗了。當我使用get()方法時,它取得了成功。我想我應該在這裏得到相同的結果。

#Model Class 
class KirrURLManager(models.Manager): 
    def all(self,*args,**kwargs): 
     qs = super(KirrURLManager,self).all(*args,**kwargs) 
     qs_main = qs.filter(active=False) 
     return qs_main 

    def refresh_shortcodes(self,items=None): 
     qs = KirrURL.objects.filter(id__gte=1) 
     if items is not None and isinstance(items,int): 
      qs = qs.order_by('-id')[:items] 
     for q in qs: 
      q.shortcode = create_shortcode(q) 
      q.save() 
      print(q.id) 
class KirrURL(models.Model): 
    url = models.CharField(max_length=220,) 
    shortcode = models.CharField(max_length=SHORTCODE_MAX,unique=True,blank=True) 
    updated = models.DateTimeField(auto_now=True) 
    timestamp = models.DateTimeField(auto_now_add=True) 
    active = models.BooleanField(default=True) 
    objects = KirrURLManager() 
    some_random = KirrURLManager() 
    def save(self, *args, **kwargs): 
     if self.shortcode is None or self.shortcode == "": 
      self.shortcode = create_shortcode(self) 
     super(KirrURL, self).save(*args, **kwargs) 
    def __str__(self): 
     return str(self.url) 
    def __unicode__(self): 
     return str(self.url) 

回答

3

您的自定義管理器產生的結果不一致,因爲.all()並不總是被調用。如果您希望此經理始終過濾特定實例,則應覆蓋get_queryset()。確保在自定義管理器上方包含默認管理器,以便您仍然可以訪問例如管理員。

class KirrURLManager(models.Manager): 
    def get_queryset(self): 
     return super().get_queryset().filter(active=False) 

class KirrURL(models.Model): 
    objects = models.Manager() # default manager, put this one first 
    custom = KirrURLManager() 

現在KurrURL.objects.all()將返回所有實例(和get_object_or_404(KirrURL, shortcode='pric3e')將能夠找到您的實例),但可以使用KirrURL.custom.all()訪問所有非活動實例。

+0

是的!謝謝它的幫助。最後我發現保存方法我重寫篩選錯誤值的問題(主動應該是這樣)。感謝您的建議。不知道get_objects_or_404會調用之前的所有方法。 – honesty1997

5

我想問題是重寫all()方法。 當您使用get_object_or_404()它是calling_get_queryset()函數返回manager.all()。但由於覆蓋all()只返回不活動的對象,並且get_object_or_404(KirrURL,shortcode='pric3e')的結果爲空。

+0

是的,謝謝!我發現問題,因爲我在我的保存方法中設置了錯誤的值。 – honesty1997