【问题标题】:Placing GeoIP IP/lat_lon Information in Django Forms在 Django 表单中放置 GeoIP IP/lat_lon 信息
【发布时间】:2012-05-25 22:46:44
【问题描述】:

我目前正在开发一个应用程序,我想将纬度和经度坐标自动插入到用户表单中。我在这里找到了一篇以前的帖子,其目的几乎完全是我试图完成的工作geocoding an IP and save using model forms,但我似乎在这个过程中犯了一个错误。我已经安装了 GeoIP 来跟踪用户的 IP 和纬度、经度。

查看代码如下:

@login_required
def submit_story(request):
if request.method =="POST":
    story_form = StoryForm(request.POST, request.FILES)
    if story_form.is_valid():
        new_story = story_form.save(ip_address=request.META['REMOTE_ADDR'])
        new_story.author = request.user
        new_story.save()
        return HttpResponseRedirect("/report/all/")
else: # GET request
    story_form = StoryForm()
return render_to_response("report/report.html", {'form': story_form}, context_instance=RequestContext(request))

这就是我认为问题所在的表格:

class StoryForm(forms.ModelForm):
    class Meta:
        model = Story
        exclude = ('author','latitude', 'longitude')

    def save(self, ip_address, *args, **kwargs):
        g = GeoIP()
        lat, lon = g.lat_lon(ip_address)
        user_location = super(StoryForm, self).save(commit=False)
        user_location.latitude = lat
        user_location.longitude = lon
        user_location.save(*args, **kwargs)

这是回溯:

Environment:


Request Method: POST
Request URL: http://localhost:8000/report/report/

Django Version: 1.3.1
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'registration',
 'profiles',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'stentorian.report',
 'south',
 'sorl.thumbnail',
 'gmapi',
 'django.contrib.admin']
Installed Middleware:
 ('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
     File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-        packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
 File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
   23.                 return view_func(request, *args, **kwargs)
 File "/Users/myname/Development/stentorian/../stentorian/report/views.py" in submit_story
  30.             new_story = story_form.save(ip_address=request.META['REMOTE_ADDR'])
 File "/Users/myname/Development/stentorian/../stentorian/report/forms.py" in save
  16.         lat, lon = g.lat_lon(ip_address)

Exception Type: TypeError at /report/report/
Exception Value: 'NoneType' object is not iterable

这是我第一次涉足地理定位和第一个 Django 项目,所以我很确定错误很简单(也许我需要拆分元组,不确定)。

【问题讨论】:

  • 带有错误的实际回溯会有所帮助。

标签: python django geolocation django-forms


【解决方案1】:

这个

lat, lon = g.lat_lon(ip_address)

导致异常,因为 g.lat_lon() 返回 None,所以它的结果 不能解压成latlon

它应该返回类似(32.0434235, 43.532522) 的东西。

这意味着您要么将无效参数传递给g.lat_lon(),要么 由于某些其他原因,它无法解析纬度/经度。

更新:

new_story = story_form.save(ip_address=request.META['REMOTE_ADDR'])

我想您是从本地工作站运行它,在这种情况下 request.META['REMOTE_ADDR'] 的值 "127.0.0.1" 显然 不是g.lat_lon()可以解决的。

在开发中,settings.DEBUG == True。因此,您可以执行以下操作

from django.conf import settings

def submit_story(request):
    remote_addr = request.META['REMOTE_ADDR']
    if settings.DEBUG:
        # We are in debug mode, so we set it to a dummy value.
        remote_addr = 'google.com'

    if request.method =="POST":
        story_form = StoryForm(request.POST, request.FILES)
        if story_form.is_valid():
            new_story = story_form.save(ip_address=remote_addr)

【讨论】:

  • 那么,考虑到视图定义了 ip_address 并且 ip_address 被传递到 lat_lon() 的参数中,还有什么其他参数可能是有效的/缺少的/需要的?非常难过。
  • @WhyNot 如果客户端(浏览器)连接来自有效的公共可​​寻址 IP,这将起作用。您可以在开发时传递一个虚拟的“google.com”作为参数,而不是 request.META['REMOTE_ADDR'](在 django 设置中 DEBUG=True)。
  • 很有可能。有没有办法将 request.META['REMOTE_ADDR'] 的值设置为静态的,看看它是否可以正常工作?编辑:我想你刚刚回答了我的问题。将尝试 (ip_address=request.META['google.com'])。
  • 从视图中获取 ip_address 的问题没有作为参数传递给表单保存。我把它改回 commit false ,它还说没有得到“提交”的论点。不知道如何解决。哦,我还将视图和表单都更改为: def save(self, *args, **kwargs): g = GeoIP() lat, lon = g.lat_lon('google.com') user_location = super(StoryForm, self ).save(commit=False) user_location.latitude = lat user_location.longitude = lon user_location.save(*args, **kwargs) (无法弄清楚如何在 cmets 中格式化代码)
  • 查看:@login_required def submit_story(request): if request.method =="POST": story_form = StoryForm(request.POST, request.FILES) if story_form.is_valid(): new_story = story_form .save(commit=False) new_story.author = request.user new_story.save() return HttpResponseRedirect("/report/all/") else: # GET request story_form = StoryForm() return render_to_response("report/report.html" , {'form': story_form}, context_instance=RequestContext(request))
【解决方案2】:

嗯...只是为了确定...您粘贴的代码中没有一些明显的缩进错误吗? 你的错误到底说明了什么?

编辑:我认为您的错误可能在于 您按名称传递 ip_address,而您将其定义为 位置 save() 方法中的 strong> 参数。顺便说一句,您链接的另一个答案中似乎也发生了这种情况...... :)

尝试在您的代码中更改这一行:

def save(self, ip_address, *args, **kwargs)

这个:

def save(self, ip_address=None, *args, **kwargs)

【讨论】:

  • 那些缺失的缩进在复制中;在实际代码中很好。这是错误:“NoneType”对象不可迭代
  • 嗯...我对stackoverflow似乎太陌生了...但是在OP上看不到任何“评论”链接:/ re。问题,您是否安装了正确的 cities 数据文件,并在您的设置中设置了正确的路径? (见django geoip docs
  • 文档中提供的测试代码在 shell 中工作,因此它似乎是可访问的。视图中的 import 语句在 PyCharm 中是灰色的(有时会这样),但在表单中没有。
  • 同样的错误。 pyCharm 使用此警报突出显示表单中的 def save() 参数:“方法签名与基本方法的签名不匹配。”不确定这是什么背景。
猜你喜欢
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2015-04-02
  • 2015-02-17
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多