简体   繁体   中英

Django filter a queryset based on another table without specified relationship

Ok so this is probably a bit of an odd question, but here is my problem. With out getting into too much detail I need to send a notice to properties but only if there is a corresponding title search. Here are my models. There is specified relationship between the two. But they share a common value in a common field. They both have a properties parcel number (the parcel number for the notice is in a related field accessible by the foreign key)

class Notice(models.Model):
    status_choice = [
        ("SendNotice", "SendNotice"),
        ("NoticeSent", "NoticeSent")
    ]

    violation_fk = models.OneToOneField(Violation, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True)
    notice_number = models.CharField(max_length=10)
    date_sent = models.DateTimeField(blank=True, null=True)
    status = models.CharField(choices=status_choice, max_length=10)
    instructions = models.TextField(blank=True, null=True)


class TitleSearch(models.Model):
    address = models.CharField(max_length=50)
    parcel_number = models.CharField( max_length=24)
    title_search_date = models.DateField(auto_now=False, auto_now_add=False)
    expiration_date = models.DateField(auto_now=False, auto_now_add=False)
    owner = models.CharField(max_length=100)
    attn_line = models.CharField(max_length=150, blank=True)
    street_address = models.CharField(max_length=150)
    city = models.CharField(max_length=25)
    state = models.CharField(max_length=2)
    zip_code = models.CharField(max_length=5)

So. here is my problem. I cannot send a notice to a property without a title search. BUT the title searches expire after a set period of time, so I don't necessarily want to tie them together.

I am trying to get a queryset that will select all the notices that have a status of "SendNotice" AND have a non expired title search on file with the same parcel number. Sort of a queryset check to make sure the parcel number is IN the list of active title searches.

Thank you,

Ok so in the meantime I have found somewhat of a janky way to work around my problem. It works but its a bit ugly.

So I couldn't find a way without creating a relationship between the two models to check for the presence of a valid title search from the notice.

as a work around I queried for all Title searches that were not expired and converted to a list of parcel numbers (the key I am using to look up across tables)

# Get list of Title Search for jank in query
active_title_searches = TitleSearch.objects.filter(expiration_date__gte=timezone.now())
active_title_searches = active_title_searches.values_list("parcel_number", flat=True)

Then I added to the filter a __in search to check to see if the parcel number from a parent table is in the list of parcel numbers of active title searches we created earlier.

# grab only notices that have title searches
ts_junk_notice = Notice.objects.filter(status="SendNotice", violation_fk__parcel_number__in=active_title_searches)

and that seems to do the trick. its sort of like a sub query to check if there is an active title search but I was reading through the django docs somewhere and it said some dbs had a hard time performing nested querys and you should do 2 simple queries instead. Hence the build a list and check within it.

I'm not sure if that helps anyone but hopefully it does.

ps I also found this package from someone else describing a similar problem that could also help you out. https://www.reddit.com/r/django/comments/7fvlf7/join_two_models_without_a_foreign_key/

https://github.com/martsberger/django-joinfield

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM