【发布时间】:2017-12-11 18:14:21
【问题描述】:
我正在尝试在我的扩展配置文件模型中保存用户 IP 地址。目标是使它成为一个隐藏的领域。目前,我可以通过将 IP 地址打印到控制台来进行调试。当我尝试保存信息时出现问题。
views.py
def index(request):
#request.session.flush()
if request.user.is_authenticated:
return redirect('ve:dashboard')
elif request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.refresh_from_db() # Load the profile instance created by the Signal
user.profile.birth_date = form.cleaned_data.get('birth_date')
user.ipaddress = get_ip(request)
print(user.ipaddress)
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('ve:dashboard')
else:
form = RegistrationForm()
return render(request, 'index.html', {'form': form})
forms.py
class RegistrationForm(UserCreationForm):
# birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')
birth_date = forms.DateField(widget=SelectDateWidget(years=range(1999, 1910, -1)))
#ipaddress = forms.IntegerField(widget=forms.HiddenInput(), required=False)
class Meta:
model = User
fields = ('username', 'email', 'birth_date', 'password1', 'password2',)
exclude = ['ipaddress',]
index.html
<form method="post">
{% csrf_token %}
{% for field in form %}
<p class="text-left">
{{ field.label_tag }}<br>
{{ field }}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
ipaddress = models.CharField(default="0.0.0.0", max_length=30)
在我尝试添加 ipaddress 字段之前,此表单运行良好。我一直在尝试几个版本,有时表单会创建一个新用户,但没有保存 ipaddress..
上面的当前代码在 POST 上给了我错误: DoesNotExist at / 用户匹配查询不存在。由于这一行 "user.refresh_from_db() # 加载 Signal 创建的配置文件实例"
【问题讨论】:
-
这将仅保存IP地址;当您执行
user.refresh_from_db()时,表单中的所有其他数据都将被替换。你为什么这样做? -
您应该使用
GenericIPAddressField,您将受益于开箱即用的验证,并且您可以同时支持 ipv4 和 ipv6 ;) -
另请注意,如果您从
RegistrationForm中取消注释ipaddress,它将在您遍历所有字段并呈现它们时呈现在您的html 中。如果您将<form method="post">的内容替换为{{ form }},它将正确呈现HiddenInput;)