2016-11-26 79 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