Performing a complex self-referencing request using Django ORM

I have the following model:

class Message(Model): url = URLField("URL") email = EmailField("E-Mail") contacted = BooleanField("Contacted", default=False) 

With examples of data such as:

 | url | email | contacted | +-----+-----------------+-----------+ | foo | foo@example.com | N | | bar | bar@example.com | N | | baz | foo@example.com | Y | 

I would like to select all individual lines (by email address) whose email addresses have never been linked. In this sample data, the string bar@example.com will be returned only.

+4
source share
2 answers

This will return the required entries:

 not_contacted = Message.objects.exclude( email__in=Message.objects.filter(contacted=True).values('email') ) 

This has the advantage that only one request is executed. Your query will look something like this:

 SELECT messages_message.id, messages_message.url, messages_message.email, messages_message.contacted FROM Messages WHERE NOT (messages_message.email IN ( SELECT U0.email from messages_message U0 WHERE U0.contacted = True ) ) 

Please note that for many, many records this query may not be optimal, but it will probably work for most purposes.

+2
source
 DROP SCHEMA tmp CASCADE; CREATE SCHEMA tmp ; SET search_path=tmp; CREATE TABLE massage ( zurl varchar NOT NULL , zemail varchar NOT NULL , contacted boolean ); INSERT into massage(zurl, zemail, contacted) VALUES ( 'foo', ' foo@example.com ', False) ,( 'bar', ' bar@example.com ', False) ,( 'baz', ' foo@example.com ', True) ; SELECT DISTINCT zemail AS zemail , MIN(zurl) AS zurl FROM massage m WHERE NOT EXISTS ( SELECT * FROM massage nx WHERE nx.zemail = m.zemail AND nx.contacted = True ) GROUP BY zemail; 

If there are several entries for a given email address, then the above selects the one that has the β€œlowest” URL. If you want them all, the query will be even simpler:

 SELECT m.zurl, m.zemail FROM massage m WHERE NOT EXISTS ( SELECT * FROM massage nx WHERE nx.zemail = m.zemail AND nx.contacted = True ) ; 
+1
source

Source: https://habr.com/ru/post/1433841/


All Articles