python seaborn - 创建一个动态选择字段




figure size (6)

我在尝试了解如何在django中创建动态选择字段时遇到了一些麻烦。 我有一个模型设置类似于:

class rider(models.Model):
     user = models.ForeignKey(User)
     waypoint = models.ManyToManyField(Waypoint)

class Waypoint(models.Model):
     lat = models.FloatField()
     lng = models.FloatField()

我想要做的是创建一个选择Field whos值是与该骑手相关的路点(这将是登录的人)。

目前我在我的表单中重写init,如下所示:

class waypointForm(forms.Form):
     def __init__(self, *args, **kwargs):
          super(joinTripForm, self).__init__(*args, **kwargs)
          self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.all()])

但所有这些都列出了所有的路标,它们并没有与任何特定的骑手相关联。 有任何想法吗? 谢谢。


Answers

有问题的内置解决方案: ModelChoiceField

通常,当您需要创建/更改数据库对象时,始终值得使用ModelForm 。 在95%的情况下工作,它比创建自己的实施更清洁。


如何在初始化时将骑手实例传递给窗体?

class WaypointForm(forms.Form):
    def __init__(self, rider, *args, **kwargs):
      super(joinTripForm, self).__init__(*args, **kwargs)
      qs = rider.Waypoint_set.all()
      self.fields['waypoints'] = forms.ChoiceField(choices=[(o.id, str(o)) for o in qs])

# In view:
rider = request.user
form = WaypointForm(rider) 

在正常选择领域下的工作解决方案。 我的问题是,每个用户都有自己的基于少数条件的CUSTOM选择字段选项。

class SupportForm(BaseForm):

    affiliated = ChoiceField(required=False, label='Fieldname', choices=[], widget=Select(attrs={'onchange': 'sysAdminCheck();'}))

    def __init__(self, *args, **kwargs):

        self.request = kwargs.pop('request', None)
        grid_id = get_user_from_request(self.request)
        for l in get_all_choices().filter(user=user_id):
            admin = 'y' if l in self.core else 'n'
            choice = (('%s_%s' % (l.name, admin)), ('%s' % l.name))
            self.affiliated_choices.append(choice)
        super(SupportForm, self).__init__(*args, **kwargs)
        self.fields['affiliated'].choices = self.affiliated_choice

正如Breedly和Liang所指出的,Ashok的解决方案将阻止您在发布表单时获得选择值。

一个稍微不同但仍不完美的解决方法是:

class waypointForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        self.base_fields['waypoints'].choices = self._do_the_choicy_thing()
        super(waypointForm, self).__init__(*args, **kwargs)

不过,这可能会导致一些并发问题。


您可以通过将用户传递给表单init来过滤航点

class waypointForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        super(waypointForm, self).__init__(*args, **kwargs)
        self.fields['waypoints'] = forms.ChoiceField(
            choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
        )

从您的视角开始,表单传递给用户

form = waypointForm(user)

在模型的情况下

class waypointForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super(waypointForm, self).__init__(*args, **kwargs)
        self.fields['waypoints'] = forms.ModelChoiceField(
            queryset=Waypoint.objects.filter(user=user)
        )

    class Meta:
        model = Waypoint

这些答案中的大部分都是对地球半径的“四舍五入”。 如果您针对其他距离计算器(如geopy)检查这些功能,则这些功能将关闭。

这很好:

lon1 = -103.548851
lat1 = 32.0004311
lon2 = -103.6041946
lat2 = 33.374939


def haversine(lat1, lon1, lat2, lon2):

      R = 3959.87433 # this is in miles.  For Earth radius in kilometers use 6372.8 km

      dLat = radians(lat2 - lat1)
      dLon = radians(lon2 - lon1)
      lat1 = radians(lat1)
      lat2 = radians(lat2)

      a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
      c = 2*asin(sqrt(a))

      return R * c

print(haversine(lat1, lon1, lat2, lon2))




python django django-forms django-templates