How to extend an admin view in Django? - python

I would like to extend the admin view used to create a new entry in the database.
For example I can create new books with their author, their categories, their date etc...
When I create a new book I want to send a notification to all users whose the book's author is one of their favorite authors.
The notification system is already working thanks to django-notifications
So, I just have to add this kind of stuff just after the book.save() in the admin view :
writer = <the_author_selected_in_the_form> # writer ID
profiles = Profile.favorites_authors.through.objects.filter(authors_id=writer)
for profile in profiles:
notify.send(profile.profile_id, recipient=profile.profile_id, verb='New book, called <book_title>, from <author_name>')
Thank you

I think "the Django way" to do that is by using signals. Something like this:
from my.book.app import Book
from django.db.models.signals import post_save
def book_created(sender, instance, **kwargs):
# Notification code goes here
if kwargs["created"]:
notify_users()
post_save.connect(book_created, sender=Book)
You can read more about them in the Django docs, also there are some great articles for beginners.

Related

Access Django DB objects without shell?

I have a request - can you help me access and manage django DB objects without using shell ?
I have created my models, but now (for example) i want to make a login system. I store users and passes(again, only an example), and i want to get the info from the DB, but i dont want to use shell.
What can i do in this case, im quite new to Django ?!
Best Regards
Why not use django-admin?
Maybe this is what you want:https://docs.djangoproject.com/en/3.0/ref/contrib/admin/
In views.py you can import
from .models import modelname
data = modelname.objects.all() - using this you can get all the data from the Database
Eg:-
for d in data:
print (d.email)
Will give all emails in the database
You can also use
t = modelname.objects.get(email='name#lk.com')
By this you can get the data of the person who's email is name#lk.com
Django already has database support where you can register your models and access them with a graphical interface.
See the documentation: django-admin-site
First you need to create a super user account, if you don't have one, create it with the terminal in the project directory, use this row:
python manage.py createsuperuser
For your model to appear on the admin site you need to register it
# models.py
class MyModel(models.Model)
field1 = models.CharField()
field2 = models.TextField()
# ...
# admin.py
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
So it's the basic way to register your model, if you want to personalize you need to check the documentation ModelAdmin.fieldsets
with this done, just access the admin site at the link http://localhost:8000/admin/ and log in with the super user account and you will see the model registered.

Is it possible to use the built-in LogEntry to track actions of every users not only in admin page?

I just recently knew about the built in LogEntry model in django, and I've tried to registered it in my admin page. What I want to happen is, for example, the admin added new User not using the django admin page but through the add page I made using some model forms in my site, how can i add data to LogEntry regarding that add action on my site? Thanks for your help!
You can easily do that in outside the admin by creating a new LogEntry object each time a change is made
from django.contrib.admin.models import LogEntry, ADDITION, CHANGE # these are action flags from the docs
LogEntry.objects.log_action(
user_id=request.user.id,
content_type_id=ContentType.objects.get_for_model(model_object).pk,
object_repr=unicode(obj.title), #or any field you wish to represent here
object_id=obj.id,
message=message, # a new user has been added
action_flag=ADDITION) # assuming it's a new object
You can read more LogEntry module in the docs
There is much more information on this here
Easy Way!
from django.contrib.admin.models import LogEntry
from datetime import datetime, timedelta
et = datetime.now()
st = et + timedelta(days=-1)
LogEntry.objects.log_action(action_time__range=[st, et])

I want to add costume field after django social app login

Hi I am php developer new to python/django
I'm creating a social login with django using 'social-auth-app-django' library and i followed following tutorial to implement it.
https://simpleisbetterthancomplex.com/tutorial/2016/10/24/how-to-add-social-login-to-django.html
Its working fine but i also need to add costume files in database which will be in different table but it will be get added when new user is created.
I have extended the user table as following
from django.contrib.auth.models import User
class NewsCreator(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
CreatorLastLogs= models.CharField(max_length=100)
CreatorLogs= models.CharField(max_length=100)
and i want to add data to these fields when a new user is created or when existing user logins. I tried going through documentation but could not found any thing that is related to code extension/customisation etc. Thanks in advance
Hi i have found answer to this so i'm posting for people who will stumble upon this post later.
django social provides pipeline to extend their code, and we just have to extend this pipeline
for this in your setting.py file post following list(all in this list are default pipeline methods which gets called except for last one).
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'newsapp.pipeline.save_profile'<-- this is your method
)
create a file in your app with name pipeline.py and name of method is to be provided in list above like last string in list (newsapp is name of my app provide your appname)
in your pipeline.py file
def save_profile(backend, user, response, *args, **kwargs):
if NewsCreator.objects.filter(user_id=user.id).count() == 0 :
newsCreator = NewsCreator.objects.create(user=user)
//your logic for new fields
newsCreator.save()
if you have any other query regarding django-social you can refer
https://github.com/python-social-auth/social-docs
its detail documentation

How to view recently client created records in django admin?

Is there any way to see recently added records as a notification in django admin? I googled but I didn't find any thing special. For example in your site you have Contacts page and each time you login to your admin panel you see notifications about new Contact model records?? Any idea how to do that?
I think, you can use django-admin-notifications module for that.
Install and configure it for your project.
Then define a new notifications.py file in Contacts app like this:
import admin_notifications
from models import Contacts
def notification():
count = Contacts.objects.filter(status=Contacts.STATUS_NEW).count()
if count:
return 'You have {} new contacts message'.format(count)
else:
return ''
admin_notifications.register(notification)

django: keep each users data separate

I am trying to workout how / the best, most secure way to keep a user's data separate within a django site that I need to write.
Here is an example of what I need to do...
example app ToDoList
Using django contrib.auth to manage users / passwords etc, I will have the following users
tom
jim
lee
There will be a ToDo model (in my real app there will be additional models)
class ToDo(models.Model):
user = models.ForeignKey(User)
description = models.CharField(max_length=20)
details = models.CharField(max_length=50)
created = models.DateTimeField('created on')
The issue that I am having - and may be over thinking this: How would this be locked down so tom can only see Tom's todo list, lee can only see his todo list and so on...
I have seen a few posts stating that you could use filter in every query, or use urls, so the url could look like www.domain.com/username/todo
But either way I am not sure if this is the right way / best way, or bonkers in terms of stopping users seeing each others data
cheers
Richard
One approach is to filter the ToDo items by the currently logged in user:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from your_app.models import ToDo
#login_required
def todos_for_user(request):
todos = ToDo.objects.filter(user=request.user)
return render(request, 'todos/index.html', {'todos' : todos})
This locks down the view for authenticated users only, and filtering by the logged in user from the request, another user, even if logged in, can't access another user's ToDo records. Hope that helps you out.
Make url like www.domain.com/username/todo is one way to implement it, but it doesn't guarantee you achieve security.
What you should do keep your user's login information in a session data after user login, and every time you check certain view,
check whether that particular user has right to see this view.
using user's login info (ID, or username) when querying user's Todo list.
And I guess this link will help you to do your job.
Sessions, Users, and Registration.

Categories

Resources