GeoDjango PointField admin visualization - django-admin

I was wondering how I could change the default PointField visualization (the Openstreetmap) in admin so that I could enter simple latitude/longitude instead of select a point on the map?
I looked at this one Latitude/longitude widget for pointfield? but could not get it working in any way in Django 1.6b4
Thanks

As Bibhas says you can override the widget used for the field, but the simple text input may not be usefull. So here is an example with a full widget that can be used for PointField of geodjango:
class LatLongWidget(forms.MultiWidget):
"""
A Widget that splits Point input into latitude/longitude text inputs.
"""
def __init__(self, attrs=None, date_format=None, time_format=None):
widgets = (forms.TextInput(attrs=attrs),
forms.TextInput(attrs=attrs))
super(LatLongWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return tuple(value.coords)
return (None, None)
def value_from_datadict(self, data, files, name):
mylat = data[name + '_0']
mylong = data[name + '_1']
try:
point = Point(float(mylat), float(mylong))
except ValueError:
return ''
return point
And now you can override your model Admin:
from django.contrib.gis.db import models as geomodels
class CompanyAdmin(admin.ModelAdmin):
list_display = ('name', 'approval', 'company_view',)
list_filter = ('approval',)
formfield_overrides = {
geomodels.PointField: {'widget': LatLongWidget},
}

You can override a widget with another in Django admin. From the documentation -
from django.db import models
from django.contrib import admin
# Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': RichTextEditorWidget},
}
This overrides TextField with RichTextEditorWidget. Just find the field type for point field and override it with TextField.

In case you are new to gis, and you don't know where point is defined, the LatLongWidget above needs to know what Point is. You can import it like this:
from django.contrib.gis.geos.point import Point

In this post I approach this issue by using two extra "Decimal Fields" in the ModelForm. This way, the Latitude and Longitude fields appear in the admin for the user's convenience without affecting the database, whatsoever.
They always reflect the relevant values if a PointField exists while they can update them or create them if the PointField does not exist.

Related

Django admin custom search on custom column

Question:
How can I add the ability to search for items in my custom column Help Text?
FooAdmin View
Code:
Here is a simplified version of the code that I am working with:
models.py (yes this is how the models need to be set up)
class HelpText(models.Model):
help_text = models.CharField(max_length=1000)
def __str__(self):
return self.help_text
class Foo(models.Model):
job_name = models.CharField(max_length=200, blank=False, null=False)
env = models.CharField(max_length=200, blank=False, null=False)
def __str__(self):
return self.job_name
class FooHelpText(models.Model):
foo = models.OneToOneField(Foo, on_delete=models.DO_NOTHING)
help_text = models.ForeignKey(HelpText, on_delete=models.DO_NOTHING)
def __str__(self):
return str(self.help_text)
admin.py
class FooHelpTextInline(admin.TabularInline):
model = models.FooHelpText
#admin.register(models.Foo)
class FooAdmin(admin.ModelAdmin):
search_fields = ['env', 'job_name',]
list_display = ['pk', 'job_name', 'env', '_get_help_text', ]
inlines = [FooHelpTextInline]
def _get_help_text(self, obj):
return obj.foohelptext.help_text
Current behavior:
The current code above allows me to see the associated help_text in a column on FooAdmin. However, I am not able to search by anything in that column.
Not the answer I am looking for:
I know if it was the other way around where the help_text was a ForeignKey on Foo I could do something like foo__help_text, but that is not how my models are set up (and can not change).
Desired behavior:
Use the search box to search for help text (not just env and job_name).
Possible Solution (that I need help with):
I suspect that get_search_results might be what I need, but I don't understand how to implement it for my use case.
UPDATE:
The closest I can get is searching for a number(aka a specific PK that I know exists) and getting that search result. But the query doesn't really make sense. And obviously that is not the desired functionality of a search.
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= models.Foo.objects.select_related(
'foohelptext').filter(fooshelptext=search_term_as_int)
return queryset, use_distinct
I just don't understand the Python |= (bitwise OR operator) and why it has to be an integer.
Much easier than I thought. No need for get_search_results.
Simply needed to add it as foohelptext__help_text__help_text as an other item in the search fields.

How to internationalize a message in grails with a hashmap (key:value)

I need to translate a message key using a Hashmap using the Grails standard internationalization method.
I receive an Enum and a map with the binding, which are going to be replaced in the text.
The Enum indicates, which key is going to be recovered. The bindings have the values to replace on the translation.
messageSource.getMessage("mail.layout.subject.${templateName}",ARGS,"",locale)
The problem is that I need to pass the map to the args like an array, not like a map, but I don't know the order of the args.
My question is, if there are any ways to create a tranlation key like:
mail.layout.subject.ENUM1=Blablabl {name} bablablabl {age}
Instead of
mail.layout.subject.ENUM1=Blablabl {0} bablablabl {1}
Finally I did it with brute force. May be is not the best answer but I coudln't find any one better.
Basically I get the translation with te message resources and then I work with it finding my custom expresions.
def messageSource = grailsApplication.getMainContext().getBean('messageSource')
def subject = messageSource.getMessage("mail.layout.subject.NOTIFICATION",null,"",locale)
An example of subject resource
mail.layout.subject.NOTIFICATION=The user {friend.name} is friend of {user}
An example bindings:
def bindings = [friend:[name:"Jhon",surname:"Smith"],user:"David"]
With this senteces I replace my expresions with the value of the bindings
Pattern pattern = Pattern.compile("\\{[^}]+\\}")
def res = subject.replaceAll(pattern,{
def expresion = it[1..it.size()-2] // removes brackets
def fields = expresion.split("\\.");
def res = bindings
fields.each{
println(it)
res = res."${it}"
}
return res
})
After the proces the subject becomes like: "The user Jhon is friend of David"
The example use a HashMap of HashMaps, but it also works with object because grails/groovy handles the object like HashMaps and viceversa
This is much cleaner. :)
import groovy.text.SimpleTemplateEngine
def text = 'Dear "$firstname $lastname",So nice to meet you in ${city.name}.See you in ${month},${signed}'
def binding = ["firstname":"Sam", "lastname":"Pullara", "city":["name":"San Francisco", "id":"28"], "month":"December", "signed":"Groovy-Dev"]
def engine = new SimpleTemplateEngine()
template = engine.createTemplate(text).make(binding)

Queries related to JIRA-Scripted Field

Is scripted field appear on ISSUE EDIT or any transition screen?
For me, it appear on issue view screen only and unable to see on issue edit screen.
I want it to appear on EDIT screen as well as a readonly.
(have verified by just keeping - "free text template" and - return "some value").
Another:
When I have use below script on scripted field then it shows me error while execute:
Error message as below:
The indexer for this field expects a java.lang.String but
the script returned a com.atlassian.jira.issue.fields.CustomFieldImpl - this will cause problems.
Code:
import com.atlassian.jira.ComponentManager.
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()
def selectedValues = customFieldManager.getCustomFieldObject("customfield_11447")
//custom field has multi selected values as it is a "multi select" field type.
return selectedValues
How I could use scripted field in issue edit/transition screen and also resolve above error.
For the first part of your question, no a scripted field wont be displayed on a Create, Edit or Transition screen. There is a work around for transition screens but I have not tried it https://gist.github.com/jechlin/5380119
Now the second part of your question. You are returning an object of CustomeField and you should be returning a String. What you want to do is
change this
def selectedValues = customFieldManager.getCustomFieldObject("customfield_11447")
to this
def cf = customFieldManager.getCustomFieldObject("customfield_11447")
def selectedValues = cf.getValue(issue)
Here is a link to the api documentation for JIRA (6.0.4):
https://developer.atlassian.com/static/javadoc/jira/6.0.4/reference/packages.html

Default django-admin list filter

My question is just an extension of this thread [Question]http://stackoverflow.com/questions/851636/default-filter-in-django-admin .
from myproject.myapp.mymodels import fieldC
class Poll(models.Model):
fieldA = models.CharField(max_length=80, choices=CHOICES.MyCHOICES)
fieldB = models.ForeignKey(fieldC)
admin.py
list_display = ('fieldB__fieldc1')
Now my list filter shows four criteria All, A ,B ,C .
What I want is if the superuser is logged in ,the filter should show all four criteria All,A,B,C and if the user is other than superuser filter should only show All, A, B.
How can i acheive this ?
Here is my actual piece of admin.py
def changelist_view(self, request, extra_context=None):
referer = request.META.get('HTTP_REFERER', '')
test = referer.split(request.META['PATH_INFO'])
if test[-1] and not test[-1].startswith('?'):
if not request.GET.has_key('patient__patient_type__exact'):
q = request.GET.copy()
q['patient__patient_type__exact'] = 'Real'
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
if not request.user.is_superuser:
q['patient__patient_type__exact'] = 'Real'
return super(VisitAdmin, self).changelist_view(request, extra_context)
Thanks in advance
I think the new FilterSpec API in Django 1.4 gives you exactly what you need here. Check out the docs on list_filter. In 1.4 you can now make custom list filters that subclass django.contrib.admin.SimpleListFilter and give you the power to write custom lookup and queryset code, and since the request is passed in you can do a simple conditional with is_superuser.
if request.user.is_superuser:
# pass one set of lookups
else:
# pass a different set
read the example code in the docs carefully and I think it will all be clear.

jQuery datepicker in Django admin without using django forms

I have a datefield named pub_date in my django project. I want to use jQuery datepicker instead of default django datepicker in django admin. But I want to do it without using django forms. Is it possible to do that? I'm giving my code below.
models.py
import datetime
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
date = models.DateField('Registration Date')
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
was_published_today.short_description = 'Published today?'
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice
admin.py
from django.contrib import admin
from poject.app.models import Poll, Choice
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
list_display = ('question', 'pub_date', 'was_published_today')
list_filter = ['pub_date']
search_fields = ['question']
date_hierarchy = 'pub_date'
admin.site.register(Poll, PollAdmin)
admin.site.register(Choice)
Is it possible to use jquery datepicker in the DateField and DateTimeField defined in the above models without using django forms?
If you don't want to create a form widget you can override the datepicker by overriding your admin change_form.html template.
Check out my question Change the default widget for date fields in Django admin about how to do this for all DateField instances.
If you don't want to touch forms, provide your own js/calendar.js and js/admin/DateTimeShortcuts.js - if you want to do this only for a particular model you'll need to override its change_form.html template and replace the default javascript files just there. What the javascript does is look for date(time) fields and insert the datepicker - yours would do the same, just with a different datepicker.

Resources