Re: check_password in contrib auth tries to update the database

2014-06-01 Thread suhridsatyal
Hi Erik,

Thanks for the explanation. This looks like something I could try.

Another approach that I found recently was to use database routers[1].
This would not cause problems with password upgrades, but we would need to 
change some database permissions.

[1] https://docs.djangoproject.com/en/dev/topics/db/multi-db/#using-routers

--
Suhrid

On Saturday, May 31, 2014 3:54:51 PM UTC+7, Erik Romijn wrote:
>
> Hello Suhrid, 
>
> On 30 May 2014, at 15:58, suhrid...@proteus-tech.com  wrote: 
> > check_password method of AbstractBaseUser in django.contrib.auth.models 
> tries to update the database. 
> > This causes problems when this code executes on a read-only slave 
> database. 
> > 
> >def check_password(self, raw_password): 
> >def setter(raw_password): 
> >self.set_password(raw_password) 
> >self.save(update_fields=["password"]) 
> >return check_password(raw_password, self.password, setter) 
>
> Yes, this is a feature, which enables upgrading of password hashing. When 
> Django encounters a password that is hashed with an older hash, the setter 
> will be called, which will save the password with the current preferred 
> hash. This can only be done when the raw password is known, which can only 
> happen while Django is checking the password. 
>
> I can see how this is an issue in your scenario. A solution I can come up 
> with is to extend this user model[1], where you override only the model's 
> check_password method. The setter parameter to check_password is optional, 
> and if absent it will simply not upgrade passwords. However, the downside 
> of this is of course, that passwords will not be upgraded if we add better 
> hashers in the future. 
>
> [1] 
> https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
>  
>
> cheers, 
> Erik

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/da273bfc-21c2-4e18-9b4a-12d019e0ba97%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: UpdateView, ModelForm - form not redirecting problem

2014-06-01 Thread Dan Gentry
What does it do instead?


>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/d58e49fa-a6f4-45e0-bf25-eedd5ebd0df9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: InlineFormSet validation

2014-06-01 Thread Russell Keith-Magee
Hi Cesar,

It's all the documentation:

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#custom-formset-validation

You just have to raise a ValidationError(); Django will then add an error
that spans the entire formset.

If you want to evaluate errors in clean(), but force the actual error to
appear against a specific field, that's possible too - you just need to
emulate what Django is doing behind the scenes. That means inserting the
error into the error dictionary, and removing the error value from
cleaned_data:

self._errors['field name'] = self.error_class(['This field has a
problems'])
del cleaned_data['field_name']

You might need to do this if you won't know if a specific value is valid
until you've checked all the individual values (e.g., A must be greater
than B - you can't check that until you know both A and B exist, which
won't be the case in the clean_A and clean_B methods)

I hope that helps!

Yours,
Russ Magee %-)



On Sun, Jun 1, 2014 at 11:52 PM, César García Tapia 
wrote:

> Hi. I already asked this question in StackOverflow, but I didn't get any
> useful answer. Let's try here :-)
>
> I have a BaseInlineFormSet, and I'd like to validate a field in the parent
> form based on the values on the fields of the children. As seen in the
> docs, the only method to make a custom validation is clean(), but I can't
> find a way to add errors to the parent form, only for the children.
>
> In the following code I build a formula. Each variable comes from a inner
> form, and if the global formula don't validate, I'd like to add an error to
> the parent's form field formula
>
> class CustomInlineFormSet(BaseInlineFormSet):
> def clean(self):
> formula = self.instance.formula
> variables = []
> for form in self.forms:
> if 'formula_variable' in form.cleaned_data:
> variables.append(form.cleaned_data['formula_variable'])
>
> valid, msg = validate_formula(formula, variables)
> if not valid:
> WHAT HERE???
>
> Thank you!!
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/87ce32a8-782e-4248-8b8c-046b6eef0904%40googlegroups.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAJxq849ckBkXM9Wbfb%2B%3DAnu5BALoN6FWT7%3DGyTDHqvp8u%2BT%3Duw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: django models

2014-06-01 Thread Tom Lockhart

On 2014-05-31, at 4:41 AM, ngangsia akumbo  wrote:

> please i need some legit answer please

Please give one or two specific examples of functionality you need. There are 
parameters for fields which can help specialize some behaviours without needing 
a new model. And there are hooks to allow specialization of behaviours in 
interpretation or handling when reading or saving values which you may find 
useful.

afaik there is no large library of model specializations for Django, but that 
may be because there is no clear large set of specializations that would be 
useful.

So give an example please. Is it the book name, the book author, or something 
else which needs extra or restricted behaviours?

- Tom


> 
> we have in the models forexaple
> 
> class Book():
> 
> name = InputTextField
> Autho = 
> 
> 
> Please are there not more parmaters that can hel you to better define your 
> model. Are there no library for models?
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-users/cb57997d-ac3e-40a4-b7f8-791db176%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Please consider the environment before printing this message.
This message may be privileged and/or confidential, and the sender does not 
waive any related rights and obligations.  Any distribution, use or copying of 
this message or the information it contains by other than an intended recipient 
is unauthorized.  If you received this message in error, please immediately 
advise me by return e-mail or phone.  All information, references, images, 
programs, source code, or other materials whatsoever contained in, or supplied 
with, this document are TRADE SECRETS and governed by the Uniform Trade Secrets 
Act.  User assumes all direct and consequential liabilities and costs that 
result from any unauthorized disclosure or use of this information.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/D64B5C18-5A49-4303-8BCC-2740FBA3B3BA%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


InlineFormSet validation

2014-06-01 Thread César García Tapia
Hi. I already asked this question in StackOverflow, but I didn't get any 
useful answer. Let's try here :-)

I have a BaseInlineFormSet, and I'd like to validate a field in the parent 
form based on the values on the fields of the children. As seen in the 
docs, the only method to make a custom validation is clean(), but I can't 
find a way to add errors to the parent form, only for the children.

In the following code I build a formula. Each variable comes from a inner 
form, and if the global formula don't validate, I'd like to add an error to 
the parent's form field formula

class CustomInlineFormSet(BaseInlineFormSet):
def clean(self):
formula = self.instance.formula
variables = []
for form in self.forms:
if 'formula_variable' in form.cleaned_data:
variables.append(form.cleaned_data['formula_variable'])

valid, msg = validate_formula(formula, variables)
if not valid:
WHAT HERE???

Thank you!!

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/87ce32a8-782e-4248-8b8c-046b6eef0904%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Transform list comprehension back to traditional looping construct, how?

2014-06-01 Thread Hannu Krosing
On 06/01/2014 03:00 PM, Pepsodent Cola wrote:
> At first I was trying to use list.append but then Python complained
> that append could only take 1 argument.  So I google around and
> list.extend said that it could take more arguments so I just went with it.
>
> What is this right method you are thinking about? 
list.append()

instead of

list.append(individual, tuple, elements)

> My imagination is very limited I only know of append but not sure how
> to work with it in this situation.
>
>
>
> On Sunday, June 1, 2014 2:52:33 PM UTC+2, Masklinn wrote:
>
>
> On 2014-06-01, at 14:29 , Pepsodent Cola  > wrote:
>
> > Hi, I want to transform my articles_list5 list comprehension
> back to a traditional looping construct to make things easier to
> read.
> > The articles_list5 returns a list of tuples.
> >
> > But when I try to do the same using traditional looping in
> articles_list6 then I just get one long list from everything.  How
> do I transform list5 to list6 correctly so it still returns a list
> of tuples?
>
> By using the right method? Why are you calling list.extend?
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users+unsubscr...@googlegroups.com
> .
> To post to this group, send email to django-users@googlegroups.com
> .
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/095e6321-4337-4bcb-b55d-07a273f515fb%40googlegroups.com
> .
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/538B40B2.90907%40krosing.net.
For more options, visit https://groups.google.com/d/optout.


Re: Save django queries for reuse

2014-06-01 Thread Derek
You have not given enough details on your reporting setup; so my guess 
would be to save the details into a new table.  This would include data 
such as:

* id (for the record)
* user_id
* report_id
* date_time
* parameters

The "parameters" are  a text field; with the criteria/parameters which 
created the report saved as a JSON object.  That way if the report gets 
extended you can still retrieve at least some of the criteria from the JSON 
data.

You might also want to allow the allow the user to give their own 
Title/Name to the report so they can more easily find it again (assuming 
you give them a list to choose from); and perhaps the option to make it 
private/public, depending on your setup.

But one thing you do not want to do is save the actual data from the 
report!!

HTH.

On Saturday, 31 May 2014 23:41:53 UTC+2, lovesh harchandani wrote:
>
> In my application a user can generate reports on multiple models using 
> multiple criteria. I want to let the user save the queries(with the 
> criteria). What is a good approach?
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/5c2290dc-4765-4a3b-9765-f89f1af7d5d9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Transform list comprehension back to traditional looping construct, how?

2014-06-01 Thread François Schiettecatte
.extend() takes as a parameter something that can be iterated over and appends 
it to the list. Something that can be iterated over includes other lists, sets, 
tuples, dictionaries, see https://docs.python.org/2/tutorial/datastructures.html

François

On Jun 1, 2014, at 9:00 AM, Pepsodent Cola  wrote:

> At first I was trying to use list.append but then Python complained that 
> append could only take 1 argument.  So I google around and list.extend said 
> that it could take more arguments so I just went with it.
> 
> What is this right method you are thinking about?  My imagination is very 
> limited I only know of append but not sure how to work with it in this 
> situation.
> 
> 
> 
> On Sunday, June 1, 2014 2:52:33 PM UTC+2, Masklinn wrote:
> 
> On 2014-06-01, at 14:29 , Pepsodent Cola  wrote: 
> 
> > Hi, I want to transform my articles_list5 list comprehension back to a 
> > traditional looping construct to make things easier to read. 
> > The articles_list5 returns a list of tuples. 
> > 
> > But when I try to do the same using traditional looping in articles_list6 
> > then I just get one long list from everything.  How do I transform list5 to 
> > list6 correctly so it still returns a list of tuples? 
> 
> By using the right method? Why are you calling list.extend?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-users/095e6321-4337-4bcb-b55d-07a273f515fb%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/C59E37CD-0920-4438-A46E-E40777B8670B%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Transform list comprehension back to traditional looping construct, how?

2014-06-01 Thread Pepsodent Cola
At first I was trying to use list.append but then Python complained that 
append could only take 1 argument.  So I google around and list.extend said 
that it could take more arguments so I just went with it.

What is this right method you are thinking about?  My imagination is very 
limited I only know of append but not sure how to work with it in this 
situation.



On Sunday, June 1, 2014 2:52:33 PM UTC+2, Masklinn wrote:
>
>
> On 2014-06-01, at 14:29 , Pepsodent Cola  > wrote: 
>
> > Hi, I want to transform my articles_list5 list comprehension back to a 
> traditional looping construct to make things easier to read. 
> > The articles_list5 returns a list of tuples. 
> > 
> > But when I try to do the same using traditional looping in 
> articles_list6 then I just get one long list from everything.  How do I 
> transform list5 to list6 correctly so it still returns a list of tuples? 
>
> By using the right method? Why are you calling list.extend?

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/095e6321-4337-4bcb-b55d-07a273f515fb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Transform list comprehension back to traditional looping construct, how?

2014-06-01 Thread Masklinn

On 2014-06-01, at 14:29 , Pepsodent Cola  wrote:

> Hi, I want to transform my articles_list5 list comprehension back to a 
> traditional looping construct to make things easier to read.
> The articles_list5 returns a list of tuples.
> 
> But when I try to do the same using traditional looping in articles_list6 
> then I just get one long list from everything.  How do I transform list5 to 
> list6 correctly so it still returns a list of tuples?

By using the right method? Why are you calling list.extend?

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/A7A551D9-B631-4203-8E2E-D5271E3F8259%40masklinn.net.
For more options, visit https://groups.google.com/d/optout.


Transform list comprehension back to traditional looping construct, how?

2014-06-01 Thread Pepsodent Cola
Hi, I want to transform my *articles_list5* list comprehension back to a 
traditional looping construct to make things easier to read.
The articles_list5 returns a list of tuples.

But when I try to do the same using traditional looping in *articles_list6* 
then I just get one long list from everything.  How do I transform list5 to 
list6 correctly so it still returns a list of tuples?


>>> *articles_list5* = [(article.id, article, article.num_publications, 
uncommented_publications, 
float(article.num_publications)/total_publicists*100) for article in 
articles]

List of tuples - :)
>>> articles_list5
[(1, , 1, [, ], 20.0),
(4, , 1, [, 
], 20.0),
(2, , 5, [, 
], 100.0),
(3, , 2, [, 
], 40.0)]


>>> articles_list6 = []
>>> 
>>> for x in articles:
... uncommented = 
Publication.objects.filter(article__pk=x.id).filter(comment='').count()
   #articles_list6.extend([x.id, x, x.num_publications, uncommented])
... *articles_list6.extend*(tuple((x.id, x, x.num_publications, 
uncommented)))
... 
>>>

List of everything - :(
>>> articles_list6
[1, , 1, 0, 
4, , 1, 0, 
2, , 5, 2, 
3, , 2, 1]
>>> 






-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/667e0a90-fd1e-4306-b074-307cb1dcf157%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Mocking Django queryset

2014-06-01 Thread Boris Ozegovic
Hi

I am having trouble mocking querysets which contains slice.  Example

qs = 
Thread.objects.filter(some_filter).order_by(some_order')[:app_settings.SEARCH_LIMIT]

And in my test I have:

Thread.objects.assert_has_calls([
mock.call.filter('some_filter'),
mock.call.filter().order_by('some_order'),
mock.call.filter().order_by().__getitem__(slice(None, 1000, 
None))
])

But this isn't working.  Message is:

Expected: [call.filter('filter'), call.filter().order_by('-post_counter'), 
('filter().order_by', (), {})]
Actual: [call.filter('filter'),
 call.filter().order_by('-post_counter'),
 call.filter().order_by().__getitem__(slice(None, 1000, None))]

Why? 

Python 2.7.5, Django 1.7b4

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/90025e4e-b8d6-4e24-9ef1-d2d919d3cd09%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: UnboundLocalError - How do I convert my pandas DataFrame into a list that Django can work with?

2014-06-01 Thread Pepsodent Cola
Never mind it seems using a tuple instead of a list solved my problem.

subset = df[[0, 1, 2, 'FRACTION']]
tuples = [tuple(x) for x in subset.values]






On Saturday, May 31, 2014 8:15:16 PM UTC+2, Pepsodent Cola wrote:
>
> Exception Type: UnboundLocalError  Exception Value: 
>
> local variable 'list' referenced before assignment
>
>
>
> Hi, I'm trying to convert my pandas DataFrame into a simple list in 
> Views.py and send it to template.  But Django complains and I don't know 
> how to make it happy.  Because when I do *"global list"* then I get the 
> below error instead which says that I cannot use variable list when I 
> google for it.  How do I convert my DataFrame into a list that Django can 
> work with?
>
>
> Exception Type: TypeError  Exception Value: 
>
> 'list' object is not callable
>
>
>
> #___
> ...
> ...
> from django.db.models import Count
>
> import pandas as pd
> import numpy as np
> import matplotlib.pyplot as plt
> pd.set_option('max_columns', 50)
>
> from magazine.models import Publication, Article
>
> #___
>
> def index(request):
>
> # Publication list
> publications = Publication.objects.all()
>
> # Articles list with Many-to-many relationship to Publication table
> # for counting how many publications each article was in.
> articles = 
> Article.objects.all().annotate(num_publications=Count('publications'))
>
> # There is a total of 5 Publications in the database.
> total_publicists = Publication.objects.all().count()
>
> #
> ### Leo magic
> articles_list = [(article, 
> float(article.num_publications)/total_publicists*100) for article in 
> articles]
> #
>
> *articles_list3* = [(article.id, article, 
> float(article.num_publications)/total_publicists*100) for article in 
> articles]
>
> df = pd.DataFrame(articles_list3)
>
> df['FRACTION'] = df[2]-df[0]
>
>
> *#global listb = map(list, df.values)*
>
> ...
> ...
>
> context = {'articles_list':articles_list, 'publications':publications,
>'total_publicists':total_publicists, 'articles':articles,
>'uncommented_publications':uncommented_publications,
>'articles_list2':articles_list2, 'b':b}
> return render(request, 'magazine/index.html', context)
>
> #___
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/6208b4df-79b3-4e37-8049-280b1d8c092e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: saving backbonejs model with django backend

2014-06-01 Thread Eddilbert Macharia
Hi,

For anyone interested or stuck as i was this is what i did in my view and 
it started working,its not working optimamly as i wanted it to but its a 
working progress but its atleast saving to the database

import json

@csrf_exempt
def saveFormDesign(request):
data=request.body
t=json.loads(data)
ClientData.objects.create(name='demo',fields=t)
return HttpResponse(t)


Regards,

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/1408467f-867f-40e1-9254-ab37a8ca2e5c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.