2010-06-15 34 views
13

Django'da not equal'a benzer SQL oluşturmak için hariç tutmayı kullanabilirsiniz. Bir örnek olabilir.Sonuçları get_object_or_404 ile nasıl hariç tutulur?

Model.objects.exclude(status='deleted') 

Şimdi bu harika çalışıyor ve hariç tutmak çok esnektir. Biraz tembel olduğum için, get_object_or_404 kullanırken bu işlevselliği almak istiyorum, ancak get_object_or_404'da hariç tutmayı kullanamadığınız için bunu yapmanın bir yolunu bulamadım. Benim istediğim

böyle bir şey yapmaktır:

model = get_object_or_404(pk=id, status__exclude='deleted') 

Ama ne yazık ki bu bir dışlama sorgu filtresi veya benzeri olmadığı gibi çalışmıyor. En iyi ben şimdiye kadar böyle bir şey yapıyor ile geldim:

object = get_object_or_404(pk=id) 
if object.status == 'deleted': 
    return HttpResponseNotfound('text') 

böyle bir şeyi yaparak, gerçekten artık kullanışlı bir liner olduğundan, get_object_or_404 kullanmanın noktası yendi.

object = get_object_or_404(pk=id, status__in=['list', 'of', 'items']) 

Ama güncel listesini tutmak gerekir gibi bu çok sürdürülebilir olmazdı:

Alternatif yapabilirdim.

İstenilen sonucu almak için get_object_or_404'u kullanmak için django'da bir numara veya özellik eksik miyim merak ediyorum?

+0

Bu gerçekten bir yanıt değil, ancak gerçekten silinmiş bir nesne için 404 istemezsiniz. Yumuşak silme noktasının tamamı, nesneyi "tam olarak" etrafında tutmaktır. –

cevap

17

Kullanım django.db.models.Q:

from django.db.models import Q 

model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id) 

Q nesneleri (~ operatörüyle) DEĞİL yapmak ve OR (| operatör ile) ek VE yılında sağlar.

Q nesnenin pk=id'dan önce gelmesi gerektiğini unutmayın, çünkü anahtar kelime bağımsız değişkenleri Python'da sonuncu olarak gelmelidir.

+0

Q nesnesinin sebebi. Yarışmaya katılacağını bilmiyordum. Teşekkürler. – googletorp

+1

Modelin yanı sıra, bir Yönetici veya bir QuerySet'i de ilk parametre olarak geçirebilirsiniz. Bkz. Http://stackoverflow.com/a/26476339/336694 – Heliodor

1

Q nesneleri kullanmak yerine başka bir yol var. Bunun yerine get_object_or_404 modeli geçme yerine sadece işlevine Sorgu Kümesi pass: Bunun

model = get_object_or_404(MyModel.objects.filter(pk=id).exclude(status='deleted'))

Bir yan etkisi, ancak, QuerySet birden çok sonuç döndürürse bir MultipleObjectsReturned istisna yükseltmek olacaktır.

6

En yaygın kullanım örneği bir Model geçirmektir. Ancak, aynı zamanda, bir QuerySet örneği geçebilir:

queryset = Model.objects.exclude(status='deleted') 
get_object_or_404(queryset, pk=1) 

Django dokümanlar, örneğin: https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#id2

+0

Bu sorunun cevabı kabul edilen cevaptan daha kolaydır. Kodumu 6 ay öncesine baktığımda, bir dışlama ile süzmek yerine bir Q nesnesi kullanmış olsaydım kendimi yüzüne yumruklamak isterdim. –

0

get_object_or_404 nesne yöneticisinin get_queryset yöntemi kullanmaktadır. get_queryset yöntemini yalnızca "silinmiş" olmayan öğeleri döndürmek için geçersiz kılarsanız, get_object_or_404 otomatik olarak istediğiniz gibi davranır. Ancak, bu gibi get_queryset'u geçersiz kılmak, muhtemelen başka yerlerde olabilir (belki de yönetici sayfalarında), ancak silinmiş öğelere erişmeniz gerektiğinde bir alternatif yönetici ekleyebilirsiniz.

from django.db import models 

class ModelManger(models.Manger): 
    def get_queryset(self): 
     return super(ModelManger, self).get_queryset().exclude(status='deleted') 

class Model(models.Model): 
    # ... model properties here ... 

    objects = ModelManager() 
    all_objects = models.Manager() 

Yani get_object_or_404(Models, id=id) yapabileceğiniz tek silinmemiş öğeleri gerekiyorsa ancak tüm öğeleri gerekirse get_object_or_404(Models.all_objects, id=id) yapabilirsiniz.

İlgili konular