مشکل برای نشون دادن اگهی ها

پرسیده شده
فعالیت 995 روز پیش
دیده شده 504 بار
0

سلام خسته نباشید.
من دارم یه پروژه مثل دیوار میزنم توی قسمت ارتقا اگهی ها(فوری ، نردبان) یه مشکلی دارم من دوتا جدول دارم یکی Promotion که این جدول برای اضافه کردن انواع ارتقا ها در نظر گرفته شده (فوری ، نردبان ، نردبان و فوری ، تمدید)
و یک جدول AdvertisementPromotion دارم که کاربر بعد از پرداخت اون اگهی با اون نوع از ارتقا توی این جدول ذخیره میشن که عکس مدلاشو گذاشتم حالا من یه کویری دارم :
 

Advertisement.objects.filter(status=Advertisement.ACCEPTED).annotate(
            time=Case(
                When(promotions__promotion=Promotion.LADDER, then='promotions__created_time'), default='created_time'
            )
        ).order_by('-time')

 

که خب وقتی اگهی نردبان بشه باید توی اون دسته بیاد سطر اگهی ها تا وقتی که یه اگهی جدید ساخته بشه سطر میمونه این تعریف خود دیوار از اگهی های نردبان : آگهی شما تا زمان دریافت آگهی تازه‌تر در همان دسته‌بندی و شهر، به عنوان اولین آگهی نمایش داده می‌شود.
 

اما مشکل اینه که اگه من بیام دستی به طور مثال برای یک اگهی هم نردبانش کنم هم فوری کنم توی جدول AdvertisementPromotion  دوتا فیلد ساخته میشه که مشکلی نیس اما با این کویری که من زدم وقتی جوینشون میکنه مثلا اگهی X یه بار تو خود Advertisement  دوبار تو  AdvertisementPromotion و وقتی جوین میخورن سه تا اگهی رو نشون میده من چیزی که کویری برمیگردونه و خود کویری رو عکسشو میزارم

میخوام ببینم مشکل از دیزاین دیتابیسه و دیزاین و باید عوض کنم

 یا کویری دیگه ای باید بزنم.

امیدوارم کامل و واضح شرح داده باشم خسته نباشید مرسی.

 

فایل پیوست
photo.zip
623.28 KB

Mohammad Mahdi Yazdani
Mohammad Mahdi Yazdani

14 مرداد 00

0
حذف شده

سلاااااااااااااااااااام محمد جان

خدا قوت

مساله از کوئری عه

توی کوئری ات باید از distinct یا distinct on استفاده کنی. و حواست باشه که هر وقت از distinct on استفاده میکنی خیلی مهمه که از order by هم درست استفاده کنی، همون طور که تو داکیومنت PostgreSQL قسمت DISTINCT Clause گفته شده:

SELECT DISTINCT ON ( expression [, ...] ) keeps only the first row of each set of rows where the given expressions evaluate to equal. The DISTINCT ON expressions are interpreted using the same rules as for ORDER BY (see above). Note that the "first row" of each set is unpredictable unless ORDER BY is used to ensure that the desired row appears first.

ترجمه:

دستور SELECT DISTINCT ON ( expression [, ...] ) فقط رکورد اول هر مجموعه از رکوردهایی که با عبارت (که معمولا یک یا چند ستون هستن) داخل پرانتز نتیجه شون یکسان بشه رو نگه میداره. عبارت های DISTINCT ON با استفاده از همان قوانین ORDER BY تفسیر میشن. حواستون باشه که «اولین رکورد» از هر مجموعه قابل پیش بینی نخواهد بود مگر اینکه از ORDER BY استفاده شده باشه برای اطمینان از اینکه رکوردهای خواسته شدن اول بیان.

 

ساده تر بخواهیم بگیم یعنی، دستور DISTINCT ON رکوردهایی رو حذف میکنه که مقدار ستون، ستون ها یا عبارتی که داخل پرانتز DISTINCT ON شون هست یکسان باشه. و حتما از دستور ORDER BY همراه DISTINCT ON استفاده کنید. چون دستور DISTINCT ON رکوردهایی بالایی رو نگه میداره.

 

سوال:

فرق DISTINCT و DISTINCT ON چیه؟ تو این مثال از کدومش باید استفاده بشه؟

یه کوئری و دستور ORM برای این کاری که گفتی بنویس و بفرس تا بیشتر در موردش صحبت کنیم.

 

محمد جان در خدمتم :)

 

منابع:

https://www.postgresqltutorial.com/postgresql-select-distinct/

https://www.postgresql.org/docs/9.5/sql-select.html

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

14 مرداد 00

0
حذف شده

سلااااااام دوباره و خسته نباشیددد

 

من چندتا کویری تست کردم و سرچ زدم اما خب الان مشکل اینه که برای مرتب سازی من از time باید استفاده کنم اما برای distinct  از advertisement_id و خوب چند مدل تست کردم اما خروجی که میخواستم و نگرفتم

 

 

Advertisement.objects.filter(status=Advertisement.ACCEPTED).annotate(
            time=Case(
                When(promotions__promotion=Promotion.LADDER, then='promotions__created_time'), default='created_time'
            )).order_by('-time', 'promotions__advertisement').distince('promotions__advertisement')

و چند مدل دیگه اما فقط اینجوری نتیجه گرفتم که کدم به نظرم خیلی درست نیس و وقتی حجم رکوردا زیاد باشه خب خیلی مشکل ایجاد میکنه

 

advertisement=Advertisement.objects.filter(status=Advertisement.ACCEPTED).distinct('promotions__advertisement').annotate(
    time=Case(
        When(promotions__promotion=Promotion.LADDER, then='promotions__created_time'), default='created_time'
    ))
    
advertisement = sorted(advertisement, key=operator.attrgetter('time'), reverse=True)

 

راه دیگه ای پیدا نکردم

فایل پیوست

Mohammad Mahdi Yazdani

توسط

Mohammad Mahdi Yazdani

18 مرداد 00

0
حذف شده

سلااااااااااااااااااااااام محمد جان

خداقوت

ایول به تلاشت

یه راه حل دیگه هم من دارم یه ستون به نام ad_datetime اضافه کنی که بصورت پیش فرض مقدار datetime.now رو میگیره و وقتی آگهی ای ارتقا نردبان پیدا میکنه. مقدار این فیلدش رو با datetime.now آپدیت کنی. و طبق این ستون order by کنی.

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

21 مرداد 00

حذف شده
توی این راه حل یه مشکلی هست اینکه دیگه بعد از سی روز نمیشه تشخیص داد کدوم اگهی کی ساخته شده و حذفش کرد چون بعد سی روز باید اگهی ها حذف بشن میشه دوتا فیلد ساخت created_time show_time زمان ساخت اگهی جفت فیلد ها datetime.now باشن اما وقتی هر اگهی اپدیت شد فیلد show_time اپدیت شه و مرتب سازی کلا روی این فیلد باشه به نظرتون این راه حل منطقی ؟ پیادش کنم همینو ؟
Mohammad Mahdi Yazdani

21 مرداد 00

حذف شده
من مساله ای در مورد این راه حل گفتی رو نفمیدم. ما ۲ تا فیلد داریم created_at و ad_datetime که وقتی آگهی ای ساخته میشه مقدار دو تاشون میشه datetime.now و وقتی آگهی ای ارتقا نردبان براش خریداری میشه مقدار ad_datetime رو با datetime.now آپدیت میکنیم و همیشه order by مون هم طبق ad_datetime هست. که شاید بشه اسم بهتری برای این فیلد ad_datetime پیدا کرد.
محمدعلی رضا

21 مرداد 00

جلسه نوشتن Query در ORM جنگو - آشنایی به Annotate و Aggregate در جنگو