Not able to save data from admin site in django app - django

I am building an app in django to keep track of social events. I am trying to handle recurring events through django-simple-events package. Issue is when I try to save any data from the admin site, it says record successfully added but when I check my model I don't see any record. When I click the object from recent activity I get an error 404 with the following message study object with primary key u'None' does not exist.
models.py
from django.db import models
from django.contrib.contenttypes import generic
from events.models import Event
class Study(models.Model):
study_event_name = models.CharField(max_length=140)
events = generic.GenericRelation(Event)
location = models.CharField(max_length=140)
def save(self):
super(Study, self).save
def __unicode__(self):
return self.study_event_name
admin.py
from django.contrib import admin
from study.models import Study
from events.admin import EventInline
# Register your models here.
class StudyAdmin(admin.ModelAdmin):
inlines = EventInline,
admin.site.register(Study, StudyAdmin)
Can anyone help me in figuring out what I am doing wrong here.

Related

How to fix "image not being saved into my database(i.e image model field)"?

I am building a Portfolio web app with Django.
I am unable to save an image into my database in my web app.
Also, to replace an existing image in the database does not work.
Note: I don't get any error message from Django. The web app will tell me no file being added.
On the Django Admin section(Django site administration page "localhost:8000/admin" I am able to add a new image and change an existing one.
How can I enable this functionality without going to django admin section.
Here's my code
views.py:
from django.views.generic.edit import CreateView, UpdateView
from django.urls import reverse_lazy
from .models import Jobs
class JobsCreateView(CreateView):
model = Jobs
fields = ['image']
template_name = "new_job.html"
class JobsUpdateView(UpdateView):
model = Jobs
fields = ['image']
template_name = "change_job.html"
success_url = reverse_lazy('home')
models.py:
from django.db import models
from django.urls import reverse
class Jobs(models.Model):
image = models.ImageField(upload_to="images/")
upload_date = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse('home', args=[str(self.id)])
If you need any additional information from me, please let me know or you can see the complete code of this project here

Unable to save model object

I have created a object which I am trying to save in Django admin in myapp>Hello. But the object does not get created under 'Hello' when I run the server. How can I fix it? I have also registered my models in admin.py.
models.py:
from django.db import models
from django.contrib.auth.models import User
class Foo(models.Model):
foo_id = models.CharField(max_length=10)
class Hello(models.Model):
user = models.ForeignKey(User, models.DO_NOTHING)
foo_id = models.ForeignKey('Foo', models.DO_NOTHING, db_column='foo_id')
foo_text = models.CharField(max_length=500, default="Hello!")
views.py
from django.shortcuts import render,HttpResponse,redirect
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import User,Foo, Hello
from django.contrib.auth import settings
#login_required
def home(request):
return render(request, 'index.html')
#login_required
def sendhello() :
Foos=Foo.objects.all()
for foo in foos:
#Hello(user=user, foo_text='hello there', foo_id=foo).save()
xyz, obj=Hello.objects.get_or_create(user=user, foo_text='hello there', foo_id=foo)
if xyz is True:
obj.save()
#login_required
def helloxyz(request):
user = User.objects.get(id=request.session['id'])
hellos=Hello.objects.filter(user_id=user)
print(hellos)
hellos_list=[]
for hello in hellos:
print(hello.hello_text)
hellos_list.append(hello.hello_text)
hellos_list.reverse()
print(hellos_list)
return render(request,'index.html',{'hellos': hellos_list,})
First of all, your sendhello function is not a view, so it does not get called when you view your site. I will for now just assume you have a JS login dialogue or someting you get inputs from. SO you want to generate DB entries from these inputs that are present (?) in your DB. You could do this by simply calling your generating function from within a view class or function (I recommend to put such non-view helper functions in a seperate file and import them in your view) or outside of views with e.g. django cron.
The simplest would be to just create a new file utilis.py, import them in your views with import myapp.utils and then call your function at the top of your site view.
Why a sperate file? It is just for better readability, is cleaner when someone else looks at your code and swapping out helpers is a bit easier.
If you have regularly occuring tasks that should best be executed independant from the user loading a specific page, take a look at the django_crontab module, it is really handy. You need to be on a Linux system dough.
I hope that answered your question

django google maps

I'm new in django. I need a google map in my model.
1. I tried to use django-google-maps.my models.py is:
from django.db import models
from django_google_maps import fields as map_fields
class Rental(models.Model):
address = map_fields.AddressField(max_length=200)
geolocation = map_fields.GeoLocationField(max_length=200)
and my admin.py:
from django.contrib import admin
from django_google_maps import widgets as map_widgets
from django_google_maps import fields as map_fields
from .models import Rental
class RentalAdmin(admin.ModelAdmin):
formfield_overrides = {
map_fields.AddressField: {'widget': map_widgets.GoogleMapsAddressWidget},
}
admin.site.register(Rental, RentalAdmin)
but when i click on the map in admin interface that fields are still empty .
I used this guide to install it https://github.com/madisona/django-google-maps
2.I tried to use easy-map by this guide http://pypi.python.org/pypi/django-easy-maps but I can't see address preview in admin interface.
my admin.py is:
from django import forms
from django.contrib import admin
from easy_maps.widgets import AddressWithMapWidget
from .models import Address
class AddressAdmin(admin.ModelAdmin):
class form(forms.ModelForm):
class Meta:
widgets = {
'address': AddressWithMapWidget({'class': 'vTextField'})
}
admin.site.register(Address, AddressAdmin)
You might be missing Google API Key in settings.py
GOOGLE_MAPS_API_KEY = 'your key here'
generate your Google Maps Javascript API from https://code.google.com/apis/console.

How to add some extra fields to the page in django-cms? (in django admin panel)

I would like to add some extra fields to pages in django-cms (in django admin panel). How do this in the simplest way?
Create a new app (called extended_cms or something) and in models.py create the following:
from django.db import models
from django.utils.translation import ugettext_lazy as _
from cms.models.pagemodel import Page
class ExtendedPage(models.Model):
page = models.ForeignKey(Page, unique=True, verbose_name=_("Page"), editable=False, related_name='extended_fields')
my_extra_field = models.CharField(...)
then create an admin.py:
from models import ExtendedPage
from cms.admin.pageadmin import PageAdmin
from cms.models.pagemodel import Page
from django.contrib import admin
class ExtendedPageAdmin(admin.StackedInline):
model = ExtendedPage
can_delete = False
PageAdmin.inlines.append(ExtendedPageAdmin)
try:
admin.site.unregister(Page)
except:
pass
admin.site.register(Page, PageAdmin)
which will add your extended model to as an inline to any page you create. The easiest way to access the extended model setttings, is to create a context processor:
from django.core.cache import cache
from django.contrib.sites.models import Site
from models import ExtendedPage
def extended_page_options(request):
cls = ExtendedPage
extended_page_options = None
try:
extended_page_options = request.current_page.extended_fields.all()[0]
except:
pass
return {
'extended_page_options' : extended_page_options,
}
and now you have access to your extra options for the current page using {{ extended_page_options.my_extra_field }} in your templates
Essentially what you are doing is creating a separate model with extra settings that is used as an inline for every CMS Page. I got this from a blog post previously so if I can find that I'll post it.
EDIT
Here is the blog post: http://ilian.i-n-i.org/extending-django-cms-page-model/
There is an official way to extend the page & title models, I highly recommend this official documentation:
Extending the page & title models from docs.django-cms.org
I also highly recommend using a placeholder if you can, since writing this answer, I now prefer creating a placeholder for the use case of cover images. (You can even get just the image URL in your template if you want to).
Summary of the link:
Create a subclass of PageExtension in your models.py file and register it:
class IconExtension(PageExtension):
image = models.ImageField(upload_to='icons')
extension_pool.register(IconExtension)
Create also a subclass of PageExtensionAdmin in your admin.py file and register it:
class IconExtensionAdmin(PageExtensionAdmin):
pass
admin.site.register(IconExtension, IconExtensionAdmin)
Finally, to make it accessible from the toolbar, create a subclass of ExtensionToolbar in cms_toolbars.py and register it:
#toolbar_pool.register
class IconExtensionToolbar(ExtensionToolbar):
model = IconExtension
def populate(self):
current_page_menu = self._setup_extension_toolbar()
if current_page_menu:
page_extension, url = self.get_page_extension_admin()
if url:
current_page_menu.add_modal_item(_('Page Icon'), url=url,
disabled=not self.toolbar.edit_mode)
The official documentation goes into more detail and explanation.
There is an open GitHub issue on adding support for adding elements to the normal and advanced "page settings" dialogues.
There's also a way to do this without using an inline, and having the fields anywhere on the Page form. For example, I have a custom setting for "color scheme" that I wanted to be under the "Basic Settings" fieldset. This can be done by overriding the ModelForm and the ModelAdmin's fieldsets. Also, I opted for a OneToOne field instead of a ForeignKey, for simplicity's sake.
models.py:
from django.db import models
from cms.models.pagemodel import Page
from django.conf import settings
class PageCustomSettings(models.Model):
page = models.OneToOneField(Page, editable=False,
related_name='custom_settings')
color_scheme = models.CharField(blank=True, choices=settings.COLOR_SCHEMES,
max_length=20)
admin.py:
from django import forms
from django.conf import settings
from django.contrib import admin
from cms.admin.pageadmin import PageAdmin, PageForm
from cms.models.pagemodel import Page
from web.models import PageCustomSettings
color_scheme_choices = (('', '---------'),) + settings.COLOR_SCHEMES
class CustomPageForm(PageForm):
color_scheme = forms.ChoiceField(choices=color_scheme_choices,
required=False)
def __init__(self, *args, **kwargs):
# make sure that when we're changing a current instance, to set the
# initial values for our custom fields
obj = kwargs.get('instance')
if obj:
try:
opts = obj.custom_settings
kwargs['initial'] = {
'color_scheme': opts.color_scheme
}
except PageCustomSettings.DoesNotExist:
pass
super(CustomPageForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
# set the custom field values when saving the form
obj = super(CustomPageForm, self).save(commit)
try:
opts = PageCustomSettings.objects.get(page=obj)
except PageCustomSettings.DoesNotExist:
opts = PageCustomSettings(page=obj)
opts.color_scheme = self.cleaned_data['color_scheme']
opts.save()
return obj
PageAdmin.form = CustomPageForm
PageAdmin.fieldsets[1][1]['fields'] += ['color_scheme']
admin.site.unregister(Page)
admin.site.register(Page, PageAdmin)
I've got here via Google and the answers got me on the right track for Django CMS 3 Beta. To extend the page model and hook your extension into the toolbar, you can follow along the official documentation:
http://django-cms.readthedocs.org/en/latest/how_to/extending_page_title.html
Access value in template
{{ request.current_page.<your_model_class_name_in_lowercase>.<field_name> }}
For example, I extended the page model with this model:
from django.db import models
from cms.extensions import PageExtension
from cms.extensions.extension_pool import extension_pool
class ShowDefaultHeaderExtension(PageExtension):
show_header = models.BooleanField(default=True)
extension_pool.register(ShowDefaultHeaderExtension)
To access its values in the template:
{{ request.current_page.showdefaultheaderextension.show_header }}
Since I dont have enough reputation I cannot comment on Timmy O'Mahony's Post directly. However I want to note that the proposed solution of adding a StackedInline Object to the PageAdmin.inlines list does not work any more as supposed.
I'm working with Djangocms 3.3 and somewhere between Timmy O'Mahony's version any mine the authors changed the semantic of the inline List. It's content is now shown in the Permissions Menu for that specific page (including possibly added futher StackedInline or TabularInline items).

Django admin - how to get all registered models in templatetag?

I'm writing a custom admin stuff and need to get all registered models in Admin. Is this possible? I need it to make some custom views on admin index page.
You can access admin.site._registry dict of Model->ModelAdmin:
>>> ./manage.py shell
In [1]: from urls import * # load admin
In [2]: from django.contrib import admin
In [3]: admin.site._registry
Out[3]:
{django.contrib.auth.models.Group: <django.contrib.auth.admin.GroupAdmin at 0x22629d0>,
django.contrib.auth.models.User: <django.contrib.auth.admin.UserAdmin at 0x2262a10>,
django.contrib.sites.models.Site: <django.contrib.sites.admin.SiteAdmin at 0x2262c90>,
testapp.models.Up: <django.contrib.admin.options.ModelAdmin at 0x2269c10>,
nashvegas.models.Migration: <nashvegas.admin.MigrationAdmin at 0x2262ad0>}
This is what the admin index view does:
#never_cache
def index(self, request, extra_context=None):
"""
Displays the main admin index page, which lists all of the installed
apps that have been registered in this site.
"""
app_dict = {}
user = request.user
for model, model_admin in self._registry.items():
# ...
Note that variables prefixed with an underscore are potentially subject to changes in future versions of django.
You can do something like this:
from django.apps import apps
models = apps.get_models()
for model in models:
try:
my_custom_admin_site.register(model)
except admin.sites.AlreadyRegistered:
pass
apps.get_models() will give all the registered models in the default Django Admin site.