Есть ли способ найти дублирующееся значение, которое имеет одинаковый адрес и дату получения в двух разных таблицах?
В настоящее время я работаю над приложением для доставки. В основном, я пытаюсь добиться того, чтобы счетчик отображал все потенциальные дубликаты заданий, которые клиент мог случайно дважды ввести.
Критерии, по которым работа считается дублированной, таковы:
- Has to have same delivery_address and same pickup_date.
Вот мои таблицы postgresql:
class Order(models.Model):
id_order = models.AutoField(primary_key=True)
class OrderDelivery(models.Model):
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
delivery_address = models.TextField()
class OrderPickup(models.Model):
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
pickup_date = models.DateField(blank=True, null=True)
Вот что я придумал на данный момент:
def dashboard_duplicated_job(orders, month):
# This function finds for jobs that has
# (1) exact pickup_date
# (2) exact delivery address
# and mark it as duplicated job.
# Find current month, if not take current year
now = timezone.localtime(timezone.now())
month = "12" if month and int(month) == 0 else month
if month == 12 or month == '12':
now = timezone.localtime(timezone.now())
last_month = now.today() + relativedelta(months=-1)
start_date = last_month.replace(day=1).strftime('%Y-%m-%d')
year = last_month.replace(day=1).strftime('%Y')
month = last_month.replace(day=1).strftime('%m')
last_day = calendar.monthrange(int(year), int(month))[1]
string_start = str(year) + "-" + str(month) + "-01"
string_end = str(year) + "-" + str(month) + "-" + str(last_day)
start_date = datetime.strptime(string_start + " 00:00:00", "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(string_end + " 23:59:59", "%Y-%m-%d %H:%M:%S")
else:
year = now.year
last = calendar.monthrange(year, int(month))[1]
string_start = str(year) + "-" + str(month) + "-01"
string_end = str(year) + "-" + str(month) + "-" + str(last)
start_date = datetime.strptime(string_start + " 00:00:00", "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(string_end + " 23:59:59", "%Y-%m-%d %H:%M:%S")
# Filter pickup_date of Orderpickup to display only orders related to current month
opu = OrderPickup.objects.filter(
order_id__in=orders,
pickup_date__range=(start_date, end_date)
).values(
'order_id',
'pickup_date',
)
# Filter OrderDelivery based on pickup_date range
ods = OrderDelivery.objects.filter(
order_id__in=opu.values('order_id')
).values(
'order_id',
'delivery_address',
# 'reference_no'
)
# Find duplicated delivery_address
dup_ods = ods.values(
'delivery_address'
).annotate(
duplicated_delivery_address=Count('delivery_address')
).filter(
duplicated_delivery_address__gt=1
)
# Extract the IDs of the duplicated delivery_address from dup_ods
dup_ods_id = ods.filter(
delivery_address__in=[item['delivery_address'] for item in dup_ods]
).values(
'order_id'
)
# Find duplicated pickup_date based on duplicated_address <not working as intended>
dup_opu = opu.filter(
order_id__in=dup_ods_id
).values(
'pickup_date'
).annotate(
duplicated_pickup_date=Count('pickup_date')
).filter(
duplicated_pickup_date__gt=1
)
dup_opu_id = opu.filter(
pickup_date__in=[item['pickup_date'] for item in dup_opu]
).order_by()
orders = orders.filter(id_order__in=dup_opu_id)
return orders
Исходя из того, что я придумал, у меня есть ситуация, когда заказы с одинаковым адресом доставки, но разной датой забора отображаются.
Пример (правильный): | delivery_address | pickup_date| | -------- | -------------- | | здесь | 08-03-2022 | | здесь | 08-03-2022 | | там| 09-03-2022 | | там | 09-03-2022 |
Пример (неверный, в настоящее время отображается): | delivery_address | pickup_date| | -------- | -------------- | | здесь | 08-03-2022 | | здесь | 08-03-2022 | | здесь | 09-03-2022 | | там| 09-03-2022 | | там | 09-03-2022 |
Посоветуйте, пожалуйста, спасибо.
UPDATE
Мне удалось решить свою проблему. Ниже приведено мое решение:
dup_job = orders.filter(
orderpickup__pickup_date__range=(start_date, end_date)
).values(
'id_order',
'orderdelivery__delivery_address',
'orderpickup__pickup_date'
).annotate(
duplicated=Count('orderdelivery__delivery_address')
).filter(
duplicated__gt=1
)