Django admin interface - django

Is it possible to display in admin interface objects that related to the current user?
For example:
class Feedback(models.Model):
to = models.ForeignKey(User)
message = models.CharField(max_length=200)
I have several admins and I want to display messages to the related admin. Thank you!

You can customize your admin site by putting a file named admin.py in your application directory, writing a ModelAdmin class for your model and overriding its queryset method, like this:
class FeedbackModelAdmin(admin.ModelAdmin):
fields = ('message',)
def queryset(self, request):
qs = super(FeedbackModelAdmin, self).queryset(request)
return qs.filter(to=request.user)
Check the full documentation of the Django admin site.

Related

Djanga admin custom list_diplay

In the Django admin panel, how do I change admin.py so that each staff can see only their data in the list_display.
For example, there is a news site. 2 staffs will add news to the site. A separate account is opened for each staff. Only the news added by that staff should appear in the list of added news. This is how it is done in list_display? Please help.
Override get_queryset in the ModelAdmin for your model
class NewsAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.filter(added_by=request.user)

Load external data into an admin model - DJANGO

Is it possible to load external data into a field for filling in?
Example: A field with for product names. However we already have the names of the products in another location, we just need to list these products within the field in the default django admin. Using resquets.
Thank you very much for your attention.
I think what you're looking for is how to customize the Django Admin, right? Check out this page in the documentation for a more detailed explanation, but here's an example that might help:
from django.contrib import admin
from .models import *
class ProductInline(admin.TabularInline):
model = Product
extra = 0
class OrderAdmin(admin.ModelAdmin):
inlines = [ProductInline]
admin.site.register(Order, OrderAdmin)
admin.site.register(Product)
This will show all of the products attached to a particular order when viewing that order from Django Admin.
You can prepopulate/fill a field in Django Admin with external data source. I guess you have some options defined somewhere outside your Django app and use those options as input for a charfield/integer field.
You can handle filling choices in a seperate Django form or overriding ModelAdmin methods. By creating a seperate form:
filter_choices = depends on your logic for loading external data
class AdminForm(forms.ModelForm):
filter_text = forms.ChoiceField(choices = filter_choices , label="Filter By",
widget=forms.Select(), required=True)
class Meta:
model = YourModel
#admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
form = AdminForm
You can try the 'formfield_for_foreignkey' method of the default ModelAdmin class
Example:
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
This example (from the original docs) will populate the 'car' field with only specific values.
Pls note that this method suits a foreinKey. I'm not sure if it fits your requirements.

Is there a way to have a field that only the superuser can add/edit?

Is there a way to have a field that only the superuser can add/edit?
class ProductPage(Page):
price = models.IntegerField(blank=True)
description = RichTextField(blank=True)
featured = models.BooleanField(default=False)
Above is part of my model but i only want the superuser to access the featured field.
I'm assuming you mean that only superusers logged in the Django admin site should be able to edit the featured field. If you want to restrict access in your own forms and views, you just need to check the user's status and customize the form/view accordingly. Here's what you can do in admin.py, in your ModelAdmin:
def get_readonly_fields(self, request):
fields = super().get_readonly_fields(request)
if not request.user.is_superuser:
fields.append('featured')
return fields
I tried out the solution given by #dirkgroten but had to make a few changes to make it work.
According to the Django Documentation for >2.1 versions of Django, the get_readonly_fields take 3 parameters.
Also, fields need to set a list to append, as it creates a tuple on default.
def get_readonly_fields(self, request, obj=None):
fields = list(super().get_readonly_fields(request))
if not request.user.is_superuser:
fields.append('featured')
return fields

How to add information from another model to admin edit page

I have 2 models.
First model contains user field and file field (address to file). It can be only one file for one user.
Second model is just the same, but it is some sort of archived files. So, it can be lot's of files for one user.
I want to add for admin edit first model page list of links for archived files from the second model for the same user.
How I can do that? What is the best way? Should I redefine admin model template and view?
Example:
User - Name
File - link to file <<<<<<<<<< I have it out of the box of django admin edit page
Archived files: <<<<<<<<< I want to add list of links to archived files
link to file1
link to file2
...
link to file N
UPD:
My models look like this:
class UserFile(models.Model):
user = models.ForeignKey(User)
file = PrivateImageField(...)
class ArchivedUserFile(models.Model):
user = models.ForeignKey(User)
file = PrivateImageField(...)
Sounds to me like you want to use Django's inline admins. Tabular inline is pretty easy to use and feature complete.
So for this code:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
You can register these admins for managing Authors, and the books they created:
from django.contrib import admin
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
Don't forget to register your admin
from django.contrib import admin
admin.site.register(Author, AuthorAdmin)
I got all of this from
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects
OR
If you just want to manage it yourself, you can edit the template. Don't
forget to put your iterator/QuerySet into the context so you can get to it.
See the docs on that.
https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#overriding-admin-templates
https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#custom-template-options
and override the change_view method on your admin.ModelAdmin:
def change_view(self, request, object_id, form_url='', extra_content=None):
// Set up vars
context = {'things': list_of_things}
return super(AuthorAdmin, self).change_view(request, object_id, form_url, context)
There's no reason you can't use inlines here. The main stumbling block will be that the User model is automatically registered in the admin. Make your ModelAdmins as so:
...
from django.contrib.auth import User
...
class UserFileInline(admin.TabularInline):
model = UserFile
class ArchivedUserFileInline(admin.TabularInline):
model = ArchivedUserFile
class UserAdmin(admin.ModelAdmin):
inlines = (
UserFileInline,
ArchivedUserFileInline,
)
# Unregister User from the admin and re-register with our ModelAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Now you can play with your files from the User admin.

Django admin site: How does the Add User page work (more fields on edit)?

I was wondering how they made it possible to display more fields in the User page of the Django admin site.
If you create a new User you only have some basic fields to fill in, but if you reopen that user (edit mode) then you see a lot more fields to fill in.
I'm trying to achieve the same, I had a look at the add_form.html template but I can't really get my head around it. I guess I'm looking for a way of specifying different fields = [] sets based on the edit status of the document.
Thanks!
The answer lies in the custom admin class registered for the User model. It overrides a couple of methods on ModelAdmin and checks to see whether the current request is creating a new User (in which case the bare-bones form class for adding accounts is used) or editing an existing one (in which case a full form is shown).
Here's my try. When I try to create a new item (Add) it shows only certain fields but then when I hit save it returns an error:
DoesNotExist
in /Library/Python/2.6/site-packages/django/db/models/fields/related.py in get, line 288
admin.py
from django.contrib import admin
from myapp.catalog.models import Model
from myapp.catalog.forms import ProductAdminForm, ProductAddForm
class ProductAdmin(admin.ModelAdmin):
form = ProductAdminForm
#...
add_form = ProductAddForm
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
})
defaults.update(kwargs)
return super(ProductAdmin, self).get_form(request, obj, **defaults)
forms.py
from myapp.catalog.models import Product
class ProductAdminForm(forms.ModelForm):
class Meta:
model = Product
#...
class ProductAddForm(forms.ModelForm):
class Meta:
model = Product
fields = ("model", "colour",)