Getting Date Widget to Display American Dates for American Users

荒凉一梦 提交于 2021-02-11 07:46:27

问题


I can use this code to detect if the user is in America

ip, is_routable = get_client_ip(request)
ip2 = requests.get('http://ip.42.pl/raw').text

if ip == "127.0.0.1":
    ip = ip2

Country = DbIpCity.get(ip, api_key='free').country

widgets.py

If the user is American I want to pass information to the template bootstrap_datetimepicker.html.

I am really unsure how to add information about the users country to the below code (which I got from another website).

class BootstrapDateTimePickerInput(DateTimeInput):
    template_name = 'widgets/bootstrap_datetimepicker.html'

    def get_context(self, name, value, attrs):
        datetimepicker_id = 'datetimepicker_{name}'.format(name=name)
        if attrs is None:
            attrs = dict()
        attrs['data-target'] = '#{id}'.format(id=datetimepicker_id)
        # attrs['data-target'] = '#{id}'.format(id=datetimepicker_id)

        attrs['class'] = 'form-control datetimepicker-input'
        context = super().get_context(name, value, attrs)
        context['widget']['datetimepicker_id'] = datetimepicker_id
        return context

bootstrap_datetimepicker.html

I want to run a different JQuery function for American users.

{% if America %}  
<script>
  $(function () {
    $("#{{ widget.datetimepicker_id }}").datetimepicker({
      // format: 'DD/MM/YYYY/YYYY HH:mm:ss',


      format: 'MM/DD/YYYY',
      changeYear: true,
      changeMonth: false,
      minDate: new Date("01/01/2015 00:00:00"),
    });
  });
</script>




{% else %}


<script>
  $(function () {
    $("#{{ widget.datetimepicker_id }}").datetimepicker({
      // format: 'DD/MM/YYYY/YYYY HH:mm:ss',


      format: 'DD/MM/YYYY',
      changeYear: true,
      changeMonth: false,
      minDate: new Date("01/01/2015 00:00:00"),
   });
  });
</script>
{% endif %}
  

回答1:


You can use Python package geoip2 to determine the location of the user (click on these two links for instructions on installing geoip2, get-visitor-location & maxminds).

from django.contrib.gis.geoip import GeoIP2

Also IP address can be extracted by the request.

ip = request.META.get("REMOTE_ADDR")

I was runnning my site on Localhost and had an issue with the above. So as a temporarily solution I did -

ip="72.229.28.185"

This was a random American IP address I found online.

g = GeoIP2()
g.country(ip)

Doing print(g) will give you something like this

{'country_code': 'US', 'country_name': 'United States'}

In your widget constructor, determine the location. Then store the country code as a context variable, like so:

from django.contrib.gis.geoip import GeoIP2

class BootstrapDateTimePickerInput(DateTimeInput):
    template_name = 'widgets/bootstrap_datetimepicker.html'

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super().__init__()

    def get_location(self):
        ip = self.request.META.get("REMOTE_ADDR")
        g = GeoIP2()
        g.country(ip)
        return g

    def get_context(self, name, value, attrs):
        datetimepicker_id = 'datetimepicker_{name}'.format(name=name)
        if attrs is None:
            attrs = dict()
        attrs['data-target'] = '#{id}'.format(id=datetimepicker_id)
        # attrs['data-target'] = '#{id}'.format(id=datetimepicker_id)

        attrs['class'] = 'form-control datetimepicker-input'
        context = super().get_context(name, value, attrs)
        context['widget']['datetimepicker_id'] = datetimepicker_id
        location = self.get_location()
        context['widget']['location'] = location['country_code']
        return context

When I was following Lewis' code I had an error. You can read more about the error here.

TypeError: 'NoneType' object is not subscriptable 

I made the below changes to Lewis' code.

def get_location(self):
    ip = self.request.META.get("REMOTE_ADDR") (or ip="72.229.28.185")
    g = GeoIP2()
    location = g.city(ip)
    location_country = location["country_code"]
    g = location_country
    return g
 
    location = self.get_location()
    context['widget']['location'] = location
    

Then where you define the widget in the form, ensure you pass request into the widget to allow you to utilise it in the widget class thus determining location. Replace <field_name> with the name of the form field.

class YourForm(forms.Form):

    [...]

    def __init__(self, *args, **kwargs):
        request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)
        self.fields[<field_name>].widget = BootstrapDateTimePickerInput(request=request)

Also in your view you must pass request into the given form:

form = YourForm(request=request)

Finally in the widget just use condition like so:

<script>
  $(function () {
    $("#{{ widget.datetimepicker_id }}").datetimepicker({
      // format: 'DD/MM/YYYY/YYYY HH:mm:ss',


      format: {% if widget.location == 'US' %}'MM/DD/YYYY'{% else %}'DD/MM/YYYY'{% endif %},
      changeYear: true,
      changeMonth: false,
      minDate: new Date("01/01/2015 00:00:00"),
    });
  });
</script>

Extra Question

I need to find a way of telling the back end if the date format is mm/dd/yyyy or dd/mm/yyyy.

  def __init__(self, *args, **kwargs):
    request = kwargs.pop('request', None)
    super().__init__(*args, **kwargs)
    self.fields['d_o_b'].widget = BootstrapDateTimePickerInput(request=request)
    (a) self.fields['d_o_b'].input_formats = ("%d/%m/%Y",)+(self.input_formats)
    (b) self.fields['d_o_b'].widget = BootstrapDateTimePickerInput(request=request, input_formats=['%d/%m/%Y'])


来源:https://stackoverflow.com/questions/63347615/getting-date-widget-to-display-american-dates-for-american-users

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!