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.
Related
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.
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.
Django: How to get yester query set in class-based views?
http://ccbv.co.uk/projects/Django/1.4/django.views.generic.dates/TodayArchiveView/
I use TodayArchiveView.
BTW, if TodayArchiveView get None, TodayArchiveView.as_view() raise Http404.
In this situation, I want to push data at yesterday in current model(table)...
What should I do?
Some Code Here:
urls.py
from django.conf.urls import patterns, include, url
from crm.views import *
urlpatterns = patterns('',
(r'^workDailyRecord/$', workDailyRecord),
)
views.py
from django.views.generic import TodayArchiveView
from django.http import Http404
from crm.models import *
def workDailyRecord(request):
if request.method === 'GET':
tView.as_view() # I want call class-based generic views at this line.
elif:
try:
return tView.as_view()(request)
except Http404:
# I want to push data at yesterday in 'WorkDailyRecord' model
pass
class tView(TodayArchiveView):
model = WorkDailyRecord
context_object_name = 'workDailyRecord'
date_field = 'date'
template_name = "workDailyRecord.html"
models.py
from django.db import models
class WorkDailyRecord(models.Model):
date = models.DateTimeField(auto_now_add=True)
contents = models.TextField()
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.
Trying to understand Django Admin a bit better, but I find the Django documentation a bit lacking sometimes (or perhaps my capacity to understand).
I know you can use fieldsets to control the layout of certain admin pages. What I can't seem to grasp is what the fieldset names are.
If I have the following class
class Demo(model.Model):
name = models.CharField(max_length=150)
address = models.CharField(max_length=150)
city = models.CharField(max_length=50)
zip = models.CharField(max_length=15)
and Admin class as the following
class DemoAdmin(admin.ModelAdmin):
list_display = ('name', 'City')
In this, albeit contrived example, what possible fieldsets could I use?
Try this, and you'll soon see how it looks/works.
class DemoAdmin(admin.ModelAdmin):
list_display = ('name', 'city')
fieldsets = (
('Standard info', {
'fields': ('name')
}),
('Address info', {
'fields': ('address', ('city', 'zip'))
}),
)
When you go to the change-page to edit, you'll get one box "standard info" with the name-box. And you'll get another box that says "address info" with the adress field first, and then the city and zip-fields on the same line after.