404'ü döndürmeden bir django görünümünde bir nesnenin var olup olmadığını doğrulamanın doğru yolu nedir?


93

Bir nesnenin var olup olmadığını doğrulamalı ve nesneyi döndürmeli, ardından bu eylemleri esas almalıyım. Bir 404'ü iade etmeden bunu yapmanın doğru yolu nedir?

try:
    listing = RealEstateListing.objects.get(slug_url = slug)
except:
    listing = None

if listing:

Rasiel, diğer cevabı kabul etmeyi düşünmeni önerebilir miyim? Bunu yapmanın doğru yolu gibi görünüyor ve kabul edilen cevaptan biraz daha fazla oy kullanılıyor.
Azendale

1
Ancak, 17 Mayıs 2010'da yayınlanan Django 1.2'de tanıtıldığını düşünebilirim, eğer sorumun 09'da gönderildiğini fark ederseniz ... bu o zaman doğru cevaptı. Exists () bunu yapmanın en iyi yolu olarak kabul edilirse, sanırım ikinci cevabı seçmek anlamsal olarak doğru olur, değil mi?
Rasiel

Rasiel, o zaman doğru yanıtın bu olduğu anlaşılıyor. Ancak yığın aşımı siteleri, siteler insanların sorunlarına çözüm bulurken, en iyi yanıtlarla bir dizi iyi / resmi soru oluşturmakla ilgilidir. Bu nedenle, şimdi "resmi olarak doğru" cevabın ne olduğunu seçme önerim.
Azendale

Bir if listing:olmalıdır else:.
Chronial

Yanıtlar:


117

404 verilmezse 404 paketleyiciyi kullanmam. Bu amacın kötüye kullanılmasıdır. Bunun yerine sadece DoesNotExist'i yakalayın.

try:
    listing = RealEstateListing.objects.get(slug_url=slug)
except RealEstateListing.DoesNotExist:
    listing = None

+1: Evet, 404'ü istemiyorsan, bu kabul edilen çözümden daha iyi bir çözüm.
Carl Meyer

yap, bu daha iyi bir çözüm gibi görünüyor
Rasiel

3
Bu çözüm exists(), nesneyle bir şeyler yapmanız gerektiğinden daha iyi çalışır .
SaeX

2
Eklemeyi seviyorum values_list('id', flat=True). eğer var mı diye listing = RealEstateListing.objects.values_list('id', flat=True).get(slug_url=slug)
bakmam

Bu sözdizimiyle ilgili garip bulduğum RealEstateListing.DoesNotExistşey, nesnenin kendisine değil modele atıfta bulunmasıdır. Neden değil RealEstateListing.objects.get(slug_url=slug).DoesNotExist?
Maxim Vallee

200

Şunları da yapabilirsiniz:

if not RealEstateListing.objects.filter(slug_url=slug).exists():
    # do stuff...

Bazen try: except:blok kullanmak daha açıktır ve diğer zamanlarda tek satırlık exists()kodun daha net görünmesini sağlar ... hepsi uygulama mantığınıza bağlıdır.



7
bu daha iyi bir yol ve cevabı olmalı
Jharwood

3
Bunun exists()işe yaramadığını varsayıyorum get(), değil mi?
Eduard Luca

9
Bu çözümün yalnızca söz konusu nesneyi kullanmayacaksanız geçerli olduğunu unutmayın. Aksi takdirde (OP'lerin durumunda olduğu gibi) yanlıştır ve kabul edilen çözümden çok daha yavaştır: Daha get()sonra yaparsanız , veritabanına ikinci bir sorgu gönderir.
Chronial

1
Eğer nesne ile bir şey (varsa) yapmak varlığını kontrol ediyoruz, o zaman ben tercih edecektir try-exceptüzerinde exists().
Jithin Pavithran

7
listing = RealEstateListing.objects.filter(slug_url=slug).first() 

2
Potansiyel nesneyi daha sonra kullanmanız gerekirse bu en iyi çözümdür, çünkü yalnızca bir atama gerektirir ve bir dene / hariç bloğu kullanmak zorunda kalmaz. Daha sonra basitçe ile varoluşu test edebileceğinizi unutmayınif listing:
Michael Hays

Denemek / hariç tutmaktan kaçınmak kötü bir uygulamadır. Yazılım Geliştirmenin en önemli yönlerinden biri, İstisnaları kontrol edebilme, bu da iyi bir kullanıcı deneyimi sağlayabilmektir. Bir şeyin düzgün çalışmadığını insanlara bildirin. İkinci; Bir QuerySet'in varlığını test etmek istiyorsanız .exists () kullanın, aksi takdirde bir nesnedir. Birincil anahtarlarıyla var olup olmadığını test edin .... if object.pk: // kod çalıştır () Bu sorgu, nesnenin tüm verilerini almaktan çok daha hızlıdır. Sadece var olup olmadığını bilmek istiyorsun.
Wolfgang Leon

2
Zaten dene / hariç ve kullanan bir çözüm vardı .exists(). SO'da işlerin nasıl yapılacağına dair birden fazla farklı cevaba sahip olmanın iyi bir fikir olduğunu düşünüyorum. Belki bu, nesneyi de varsa kullanmak isteyenler için daha iyidir. Denemek / hariç tutmaktan kaçınılmalı ya da kaçınılmalıysa herhangi bir kural koymam. Bazen iyidir ve bazen kötüdür, örneğin sadece çok kompakt bir kod yapmak istiyorsanız.
Henrik Heino

0

Bunu şu kadar basit yapardım:

listing = RealEstateListing.objects.filter(slug_url=slug)
if listing:
    # do stuff

Denemeye / yakalamaya gerek görmüyorum. Sonuçta potansiyel olarak birkaç nesne varsa, önce () kullanıcısı Henrik Heino tarafından gösterildiği gibi kullanın.


Sorgu kümesinde .first () veya koşullu olarak .first () yapmazsanız, bu her zaman True döndürür.
B.Adler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.