Geodjango admin, display pointfield not as map - django

This may be a stupid question but I can't find any clear answers.
How do I change the display in the Django Admin so the Pointfield does not show up like a OpenLayer Map but as a regular input field. I need to see the long, lat for debugging..
Do i have to change the field type? Widgets?
Thanks!

Update
This is how I managed -at last- to keep separate fields for lattitude and longitude without having to save them in the database since the values are already saved in the PointField.
The idea is :
If we are inserting a new entry, the latitude and longitude fields will be used to set the PointField
If we open an existing PointField entry, it will be used to provide the latitude and longitude values in the relevant FormFields.
models.py
from django.contrib.gis.db import models as geomodels
class Entry(geomodels.Model):
point = geomodels.PointField(
srid=4326,
blank=True,
)
admin.py
from myapp.forms import EntryForm
from django.contrib import admin
class EntryAdmin(admin.ModelAdmin):
form = EntryForm
admin.site.register(Entry, EntryAdmin)
forms.py
from django import forms
from myapp.models import Entry
from django.contrib.gis.geos import Point
class MarketEntryForm(forms.ModelForm):
latitude = forms.FloatField(
min_value=-90,
max_value=90,
required=True,
)
longitude = forms.FloatField(
min_value=-180,
max_value=180,
required=True,
)
class Meta(object):
model = MarketEntry
exclude = []
widgets = {'point': forms.HiddenInput()}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
coordinates = self.initial.get('point', None)
if isinstance(coordinates, Point):
self.initial['longitude'], self.initial['latitude'] = coordinates.tuple
def clean(self):
data = super().clean()
latitude = data.get('latitude')
longitude = data.get('longitude')
point = data.get('point')
if latitude and longitude and not point:
data['point'] = Point(longitude, latitude)
return data
From the source code of PointField we see that its form class uses the OpenLayersWidget which inherits from the BaseGeometryWidget.
The conclusion is that in this class, the variable display_raw is by default set to False.
If you set it to True in yourapp/admin.py, you will get a textbox with lat and long and other data, useful for debugging purposes:
from django.contrib.gis import admin
from yourapp.models import YourClass
from django.contrib.gis import forms
from django.contrib.gis.db import models
class YourClassAdminForm(forms.ModelForm):
your_attribute = forms.PointField(widget=forms.OSMWidget(attrs={
'display_raw': True}))
class YourClassAdmin(admin.GeoModelAdmin):
form = YourClassAdminForm
admin.site.register(YourClass, YourClassAdmin)
There is also a way to have both a map and manual insertion of longitude / latitude permanently (not only for debugging).
The idea is to use FloatFields to insert the Longitude/Latitude and update the PointField with the inserted data.

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.

Related

Django - oscar show a field in dashboard

from oscar.apps.catalogue.abstract_models import AbstractProduct
from oscar.core.compat import AUTH_USER_MODEL
from django.db import models
class Product(AbstractProduct):
seller = models.ForeignKey(
AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True)
from oscar.apps.catalogue.models import *
I added this code to forked catalog model >
I want to show it in the dashboard,Image of dashboard and dropdown box I tried admin.site.register but it is not working.
This is the code for override of form , when I fork and overrtide it doesn't work but when I change the code in core it works .
from oscar.apps.dashboard.catalogue.forms import ProductForm
from oscar.core.loading import get_class, get_classes, get_model
from yourappsfolder.catalogue.models import Product
class SellerField(ProductForm):
class Meta(ProductForm.Meta):
model =Product
fields = [
'title','seller', 'upc', 'description', 'is_public', 'is_discountable', 'structure']
You have forked the form incorrectly. Calling your form class SellerField will not work. The form class needs to have exactly the same name as the core form, otherwise Oscar's loader will not find it. Change it like this:
from oscar.apps.dashboard.catalogue.forms import ProductForm as BaseProductForm
class ProductForm(BaseProductForm):
class Meta(BaseProductForm.Meta):
fields = ['title','seller', 'upc', 'description', 'is_public', 'is_discountable', 'structure']

Which library is used for importing RadioInput (widgets) in forms.py in Django?

I am using radio buttons for user input in forms.py and want to save the rated value in django database.I have the following fields:
from product.models import Rating
from django.forms import forms
from django.forms.fields import ChoiceField
from django.forms import ModelForm
from django import forms
class RatingForm(forms.ModelForm):
class Meta:
model = Rating
fields = ('product', 'user', 'rating')
widgets = forms.ChoiceField(widget=forms.RadioInput(),
required=True)
Model.py
class Rating(models.Model):
CHOICES = (
('5-stars', '5-stars'),
('4-stars', '4-stars'),
('3-stars', '3-stars'),
('2-stars', '2-stars'),
('1-stars', '1-stars'),
)
product=models.ForeignKey(Product,null=True,blank=True, on_delete=models.PROTECT)
user=models.ForeignKey(User,null=True,blank=True, on_delete=models.PROTECT)
rating=models.ChoiceField(choices=CHOICES, max_length=128)
I didn't find any library for importing this widget. Below is the error i am facing:
AttributeError: module 'django.forms' has no attribute 'RadioInput'?
Please if any one can help? Or suggest any other way to do this?
The widget is called RadioSelect, not RadioWidget. See the documentation.
Note however, you must use the widget directly in the widgets attribute, not as part of a field; and widgets is a dictionary of field names to widgets:
widgets = {'rating': forms.RadioSelect}

I want to add a location field in django model which take location input by putting lattitude and longitude

I also want to pick the location through Django REST API Through template..please suggest necessary django packages for it and how to write locationField in the Django Model
this is the picture that django location field exactly which I want to Add please see it..
You can create the multiple inputs field subclassing MultiValueField:
class Location:
def __init__(self, latitude, longitude):
self.latitude = latitude
self.longitude = longitude
class LocationField(MultiValueField):
def __init__(self, *args, **kwargs):
fields = (
FloatField(max_value=90, min_value=-90),
FloatField((max_value=90, min_value=-90)
)
super().__init__(*args, **kwargs)
def compress(self, data_list):
latitude, longitude = data_list
return Location(latitude, longitude)
As for the second question, sorry, but it's very unclear what you are asking for.
I will try to be precise, I have build one similar project.
As you described in image in the link.
The following would do the job.
Make these changes in settings.py
'django.contrib.gis.db.backends.postgis',
Install this package https://pypi.org/project/django-map-widgets/
Add the below lines in Installed Apps:
'django.contrib.gis',
'mapwidgets'
Add these variables:
GOOGLE_MAP_API_KEY = "Create a google_map_api_key_and_past_it_here"
MAP_WIDGETS = {
"GOOGLE_MAP_API_KEY": "Create a google_map_api_key_and_past_it_here"
}
In the models.py:
from django.contrib.gis.db import models
from django.contrib.gis.geos import Point
class Stack(models.Model):
location = models.PointField(geography=True, spatial_index=True)
In forms.py:
from django.contrib.gis import forms as gis_forms
from django.contrib.gis.db import models as gis_models
from mapwidgets.widgets import GooglePointFieldWidget
class GoogleAddressForm(gis_forms.ModelForm):
location = gis_forms.PointField(
widget=widgets.GooglePointFieldWidget(
),
)
class Meta:
model = Point
fields = "__all__"
formfield_overrides = {
gis_models.PointField: {"widget": widgets.GooglePointFieldWidget()}
}
In view simply render the template and pass the form in context.
In template using {{form.location}} would render the exact image with all those functionalities.

Django models and admin panel

Hi guys I have this model
class Class1(models.Model):
....
ctime = models.FloatField() # I am storing date in timestamp here
....
Is it possible to display ctime field in admin panel not as float but as time field?
Check Django documentation. You can override default widgets for model fields -
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},
}
Or, for a single model, as described in this answer -
class StopAdminForm(forms.ModelForm):
class Meta:
model = Stop
widgets = {
'approve_ts': ApproveStopWidget(),
}
class StopAdmin(admin.ModelAdmin):
form = StopAdminForm
Check other answers in that question too.a

in django admin, can we have a multiple select based on choices

http://docs.djangoproject.com/en/dev/ref/models/fields/#choices
i've read through the documentation and this implies using a database table for dynamic data, however it states
choices is meant for static data that doesn't change much, if ever.
so what if i want to use choices, but have it select multiple because the data i'm using is quite static, e.g days of the week.
is there anyway to achieve this without a database table?
ChoiceField is not really suitable for multiple choices, instead I would use a ManyToManyField. Ignore the fact that Choices can be used instead of ForeignKey for static data for now. If it turns out to be a performance issue, there are ways to represent this differently (one being a binary mask approach), but they require way more work.
This worked for me:
1) create a Form class and set an attribute to provide your static choices to a MultipleChoiceField
from django import forms
from myapp.models import MyModel, MYCHOICES
class MyForm(forms.ModelForm):
myfield = forms.MultipleChoiceField(choices=MYCHOICES, widget=forms.SelectMultiple)
class Meta:
model = MyModel
2) then, if you're using the admin interface, set the form attribute in your admin class so tit will use your customized form
from myapp.models import MyModel
from myapp.forms import MyForm
from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
form = MyForm
admin.site.register(MyModel, MyAdmin)
Try following configuration. In models.py
class MyModel(models.Model):
my_choices = models.TextField(help_text="It's a good manners to write it")
in forms.py
CHOICES = ((1,1), (2,2))
class MyForm(forms.ModelForm):
my_choices = forms.MultipleChoiceField(choices=CHOICES)
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
# maybe you can set initial with self.fields['my_choices'].initial = initial
# but it doesn't work wity dynamic choices
obj = kwargs.get('instance')
if obj:
initial = [i for i in obj.my_choices.split(',')]
self.initial['my_choices'] = initial
def clean_lead_fields(self):
return ','.join(self.cleaned_data.get('my_choices', []))
in admin.py
#admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm