Reputation: 710
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 %}
Upvotes: 1
Views: 161
Reputation: 2798
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'])
Upvotes: 1