这让我大吃一惊,把我吓坏了。
我这里有一个注册页面:http: //eatfeastly.com(我在 8 月 15 日午夜重新启动了服务器,暂时解决了问题,所以您可能需要等待才能看到问题)
您会注意到它已经预先填充了一些用户的电子邮件。请注意,这意味着此数据不仅在我的缓存中。不用说,这对我们的用户来说是坏事。
为此,我使用以下 MVT:
模型
class PotentialUser(CommonInfo):
is_cook = models.BooleanField()
email = models.EmailField(unique=True, db_index=True, validators=[validate_no_existing_user_email])
location = models.CharField(max_length=500, help_text="Please enter city, state.")
zipcode = models.CharField(max_length=10, blank=True)
class LOCATION:
DC = "Washington, DC"
NY = "New York City, NY"
SF = "San Francisco, CA"
OTHER = "Other"
def __unicode__(self):
return self.email
def send_signup_email(self):
# Can't use django notifications here, since it requires an actual user, and this is only a potential user
msg = MultipartTemplateEmailMessage('signup_complete',
from_email=settings.DEFAULT_FROM_EMAIL,
to=[self.email],
part_templates=(
('full.txt', 'text/plain'),
),
context={
'recipient': self,
'support_email': settings.SUPPORT_EMAIL,
# shortened from:
# http://eatfeastly.com/?utm_source=cont-e-pot&utm_medium=email-auto&utm_content=feedme&utm_campaign=e-share
'share_url': "http://goo.gl/X2VtA",
},
)
msg.send()
形式
class PotentialUserModelForm(forms.ModelForm):
# Override to make this field required
is_cook = forms.TypedChoiceField(
required=True,
coerce=bool,
choices=(
('cook', True),
('feaster', False),
('both', True),
)
)
class Meta:
model = PotentialUser
def clean(self):
cleaned_data = super(PotentialUserModelForm, self).clean()
location = cleaned_data.get('location')
if location == "Other":
zipcode = cleaned_data.get('zipcode')
if zipcode is None or zipcode == '':
if not 'zipcode' in self._errors:
self._errors['zipcode'] = ErrorList()
self._errors['zipcode'].append("Zipcode is required")
del cleaned_data['zipcode']
return cleaned_data
看法
class PotentialUserCreateView(CreateView):
form_class = PotentialUserModelForm
template_name = "intro/home.html"
form_focused = False
def get_success_url(self):
return reverse_lazy('potential_user_thanks', self.object.pk)
def get_context_data(self, **kwargs):
kwargs['LOCATION'] = PotentialUser.LOCATION
if self.form_focused or hasattr(kwargs['form'], 'errors') and kwargs['form'].errors:
kwargs['form_focused'] = True
else:
kwargs['form_focused'] = False
return super(PotentialUserCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
# Save the user to the database and set self.object
response = super(PotentialUserCreateView, self).form_valid(form)
self.object.send_signup_email()
return response
模板
<!-- ... -->
<form id="intro_form" action="{% url signup %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div id="intro_form_box" class="vcenter_outer">
<div class="field_container">
{{ form.email.errors }}
<label for="email">Email</label>
<input id="email" name="email" type="text" placeholder="yourname@domain.com"
value="{{ form.email.value|default_if_none:'' }}"/>
</div>
<div class="field_container">
{{ form.is_cook.errors }}
<span>I'm a</span>
<input type="radio" id="cook_button" class="form_button" name="is_cook"
{% if form.is_cook.value == 'cook' %}checked="checked"{% endif %} value="cook"/>
<label for="cook_button">Cook</label>
<input type="radio" id="feaster_button" class="form_button" name="is_cook"
{% if form.is_cook.value == 'feaster' %}checked="checked"{% endif %} value="feaster"/>
<label for="feaster_button">Feaster</label>
<input type="radio" id="both_button" class="form_button" name="is_cook"
{% if form.is_cook.value == 'both' %}checked="checked"{% endif %} value="both"/>
<label for="both_button">Both</label>
</div>
<div class="field_container">
{{ form.location.errors }}
<span>from</span>
{# These location values should match the Area values in the database #}
<input type="radio" id="dc_button" class="form_button" name="location"
{% if form.location.value == LOCATION.DC %}checked="checked"{% endif %} value="{{ LOCATION.DC }}"/>
<label for="dc_button">{{ LOCATION.DC }}</label>
<input type="radio" id="ny_button" class="form_button" name="location"
{% if form.location.value == LOCATION.NY %}checked="checked"{% endif %} value="{{ LOCATION.NY }}"/>
<label for="ny_button">{{ LOCATION.NY }}</label>
<input type="radio" id="sf_button" class="form_button" name="location"
{% if form.location.value == LOCATION.SF %}checked="checked"{% endif %} value="{{ LOCATION.SF }}"/>
<label for="sf_button">{{ LOCATION.SF }}</label>
<input type="radio" id="other_button" class="form_button" name="location"
{% if form.location.value == LOCATION.OTHER %}checked="checked"{% endif %} value="{{ LOCATION.OTHER }}"/>
<label for="other_button">Other</label>
<div id="zipcode_container"
{# only show the container if other is checked or there are validation errors #}
{% if form.zipcode.errors %}
class="field_error"
{% else %}{% if form.location.value != LOCATION.OTHER %}
style="display:none;"
{% endif %}{% endif %}
>
<div>
<span>
Sorry Feastly only works in select cities at the moment.<br/>
<b>Enter your zip code</b> and we'll let you know when you can join!
</span>
<label>
{{ form.zipcode.errors }}
<input type="text" id="other_location" name="zipcode" maxlength="5"
value="{{ form.zipcode.value|default_if_none:'' }}"
placeholder="zip code"/>
</label>
</div>
</div>
</div>
</div>
<button id="feed_me" type="submit">Feed me!</button>
</form>
<!-- ... -->
这是谜题的另一个奇怪部分:一些用户的电子邮件在数据库中没有关联的 PotentialUser 模型,而是有一个 Django User 模型。
现在这是关键:它不会发生在我的开发机器上,也不会发生在我们的暂存环境中。这两种环境都有自己的覆盖设置,但似乎没有任何影响。我只是自己测试过这个。
然而,似乎解决它的方法是重新启动服务器。在发生某些事情之前,另一个用户在另一台计算机上登录或其他东西(!?),并且用户的电子邮件开始显示在注册页面上。
这可能是什么原因造成的?这可能是用户的会话泄漏到其他连接吗?如果是这样,那是如何工作/发生的?最重要的是,我应该如何解决这个问题?
谢谢!