Looking for some guidance because I'm entering new territory here in terms of my Django experience. I'm writing a reprographics request app so have created a couple of models:
class Job(models.Model):
id = models.AutoField(primary_key=True) # AutoField?
class Resource(models.Model):
id = models.AutoField(primary_key=True) # AutoField?
job = models.ForeignKey(Job)
file = models.FileField(upload_to="repro/")
The admin view includes the resource as inline
class ResourceInline(admin.TabularInline):
model = Resource
extra = 0
class JobAdmin(admin.ModelAdmin):
model = Job
list_display = ['requestedby','account','requestdate','requireddate','noofsides','noofcopies']
list_filter = ['requireddate']
search_fields = ['requestedby','account']
form = JobForm
fieldsets = [
(None, {'fields': ['requestedby','account','requestdate','requireddate','noofsides','noofcopies'] }),
('Requirements', {'fields': ['color','sided','paper','finishing']}),
('Additional Information', {'fields': ['additionalinfo']}),
]
inlines = [ResourceInline]
admin.site.register(Job,JobAdmin)
I'm planning to use dropzone.js and have got myself a change_form.html that I can customise but at this point I'm a bit lost. How can I replace the inline with my dropzone area and get it working?
Thanks for any help or pointers.
Chris
Use adminsortable2 to drag and drop in Django Admin. This is the github link.
So in you case, the code with adminsortable2 is this below.
"models.py":
from django.db import models
class Job(models.Model):
id = models.AutoField(primary_key=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
class Resource(models.Model):
id = models.AutoField(primary_key=True)
job = models.ForeignKey(Job)
file = models.FileField(upload_to="repro/")
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
"admin.js":
from django.contrib import admin
from adminsortable2.admin import SortableAdminMixin, SortableInlineAdminMixin
from .models import Job, Resource
class ResourceInline(SortableInlineAdminMixin, admin.TabularInline):
model = Resource
extra = 0
#admin.register(Job)
class JobAdmin(SortableAdminMixin, admin.ModelAdmin):
list_display = ['requestedby','account','requestdate','requireddate','noofsides','noofcopies']
list_filter = ['requireddate']
search_fields = ['requestedby','account']
form = JobForm
fieldsets = [
(None, {'fields': ['requestedby','account','requestdate','requireddate','noofsides','noofcopies'] }),
('Requirements', {'fields': ['color','sided','paper','finishing']}),
('Additional Information', {'fields': ['additionalinfo']}),
]
inlines = [ResourceInline]
Then, run this command below after writing the code above to save your sorting:
python manage.py reorder <app.model>
So, in your case, I don't know your app name so if your app name is "work" and I know your model names "Job" and "Resource" so run this command below to save your sorting:
python manage.py reorder work.Job work.Resource
Related
I am currently using Django REST framework 3.11.0 with Django 3.0.6. I am still very new to DRF and I am not sure how to approach this problem. I am trying to apply sort to SerializerMethodField and an enum. I was able to find some documentation that states that I could make my own OrderFilter but I dont know how. Are there any examples I could use? Here is my code.
View
from rest_framework import generics
from V1.assets.models.asset_main import Asset
from V1.assets.serializers.asset_serializer import AssetSerializer
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
class AssetsView(generics.ListCreateAPIView):
queryset = Asset.objects.all()
serializer_class = AssetSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filter_fields = ['asset_type']
search_fields = ['asset_type', 'asset_properties', 'current_employee_name']
Model
class AssetType(models.TextChoices):
LAPTOP = 'LPT', _('Laptop')
MOUSE = 'MSE', _('Mouse')
MONITOR = 'MTR', _('Monitor')
AC_ADAPTER = 'ADR', _('AC Adapter')
TELEPHONE = 'TLP', _('Telephone')
LOCK = 'LCK', _('Lock')
HEADSET = 'HDS', _('Headset')
class Asset(CreatedModified):
asset_type = models.CharField(
max_length=3,
choices=AssetType.choices,
default=None
)
asset_properties = JSONField(default=dict)
current_employee = models.ForeignKey(
Employee,
related_name='assets_current_employees',
related_query_name='assets_current_employee',
default=None,
on_delete=models.CASCADE,
null=True,
blank=True
)
class Meta:
app_label = 'assets'
default_related_name = 'assets'
def __str__(self):
return self.asset_type
Serializer
from V1.general.enums import AssetStatus, AssetType
from V1.accounts.models.employee_main import Employee
class AssetSerializer(serializers.ModelSerializer):
current_employee_name = serializers.SerializerMethodField('get_full_name_from_employee')
asset_type = serializers.CharField(source='get_asset_type_display')
class Meta:
model = Asset
fields = (
'id',
'asset_type',
'asset_properties',
'current_employee',
'current_employee_name'
)
extra_kwargs = {
'asset_type': {
'required': True,
'allow_blank': False
}
}
def get_full_name_from_employee(self, asset):
current_employee_name = asset.current_employee.first_name + ' ' + asset.current_employee.last_name
return current_employee_name
I can't seem to order by current_employee_name or asset_type. What should I do to allow sorting for these two fields?
As far as I can understand from your question you want to order the Assets by the current employee name. Let's take few names for example:
Jean d'Artagnan (first_name: Jean, last_name: d'Artagnan)
Joe Plumber (first_name: Joe, last_name: Plumber)
Jonas Meyer (first_name: Jonas, last_name: Meyer)
The same ordering can be achieved if we sort first by first_name and then by last_name. In case there are multiple entries with the same first_name the ordering will be done be the last_name.
To achieve this you can simply specify the ordering_fields in your view:
class AssetsView(generics.ListCreateAPIView):
filters = [filters.OrderingFilter]
ordering_fields = ['current_employee.first_name', 'current_employee.last_name']
I have a model where I have list of servers...
Here is my model:
class Ipaddress(models.Model):
ip_address=models.CharField("Ip address",max_length=20)
device_type= models.ForeignKey("DeviceType", on_delete=models.CASCADE)
slug = models.SlugField(unique=True)
machine_name=models.CharField("Machine Name",max_length=500)
user=models.CharField("User",max_length=200)
department= models.ForeignKey("Department", on_delete=models.CASCADE)
location= models.ForeignKey("Location", on_delete=models.CASCADE)
updated = models.DateField("Date Updated",null=True)
note =models.TextField()
class Meta:
verbose_name = 'IP Management'
def __str__(self):
return self.ip_address[:50]
I want to add ping server action for every model record and store "Yes" if it revived any response. Here is admin page:
from django.contrib import admin
from pages.models import Ipaddress, DeviceGroup, Location,Department,
from django_admin_listfilter_dropdown.filters import DropdownFilter, RelatedDropdownFilter
class DepartmentAdmin(admin.ModelAdmin):
search_fields = ['name']
class LocationAdmin(admin.ModelAdmin):
search_fields = ['description']
list_display =('description',)
class IpaddressAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('ip_address',)}
search_fields = ('ip_address', 'machine_name')
list_display = ('ip_address', 'device_type', 'machine_name', 'user', 'department','location','updated',)
list_display_links =('ip_address', 'device_type', 'machine_name', 'user', 'department','location','updated',)
autocomplete_fields = ['location','department',]
list_filter = (
('user', DropdownFilter),
('department', RelatedDropdownFilter),
('location', RelatedDropdownFilter),
('device_type', RelatedDropdownFilter),
)
I am thinking to add a button to pop up a small dialog box from where user will confirm ping. Need some help how I can do that?
Please help me. I gave up. I am trying to add additional field to my django admin. I would like to insert image thumbnail there. This is part of my admin.py:
class SiteAdmin(admin.ModelAdmin):
list_display = ('is_active', 'name', 'description', 'keywords', 'date')
fields = ('name', 'url', 'category', 'subcategory', 'category1',
'subcategory1', 'description',
'keywords', 'date', 'group', 'email', 'is_active')
readonly_fields = ('date',)
list_display_links = ('name',)
list_filter = ('is_active',)
actions = [activate_sites, deactivate_sites]
I wolud like to add 'image' to list_display. Images are generating by thumbalizr. I have a method in models.py:
class Site(models.Model):
category = models.ForeignKey('Category')
subcategory = ChainedForeignKey(
'SubCategory',
chained_field='category',
chained_model_field='category',
show_all=False,
auto_choose=True,
blank=True, null=True, default=None)
name = models.CharField(max_length=70, verbose_name="Tytuł")
description = models.TextField(verbose_name="Opis")
keywords = MyTextField(max_length=100, verbose_name="Słowa kluczowe")
date = models.DateTimeField(default=datetime.now, editable=False)
url = models.URLField()
is_active = models.BooleanField(default=False)
category1 = models.ForeignKey('Category', related_name='category', blank=True, null=True, default=None)
subcategory1 = ChainedForeignKey(
'SubCategory',
chained_field='category1',
chained_model_field='category',
related_name='subcategory',
show_all=False,
auto_choose=True, blank=True, null=True)
group = models.CharField(max_length=10, choices=(('podstawowy', 'podstawowy'),
('premium', 'premium')), default='podstawowy',
help_text="<div id='group'><ul><li>You can add site to 2 <b>categories</b></li></ul></div>")
email = models.EmailField(help_text='Podaj adres email')
def get_absolute_url(self):
return reverse('site', args=[str(self.category.slug),
str(self.subcategory.slug), str(self.id)])
def get_thumb(self):
host = urlparse(self.url).hostname
if host.startswith('www.'):
host = host[4:]
thumb = 'https://api.thumbalizr.com/?url=http://' + host + '&width=125'
return thumb
It is get_thumb(). How can I take image to every site and put in in my django admin page? Should I add additional field to my Site model? I don't want to store images on my server - they are directly from thumbalizr.
You should add a method into your modeladmin class. Then you can add this method into your field list.
class SiteAdmin(admin.ModelAdmin):
list_display = [..., 'thumb']
...
...
def thumb(self, obj):
return "<img src='{}' width='20' height='20' />".format(obj.get_thumb())
thumb.allow_tags = True
thumb.__name__ = 'Thumb'
https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
I was solving this problem in latest django 2.0.6. I wanted to achiave to have image thubnail and some more details in listview in django-admin.
I post answer here:
Django: Display image in admin interface
You can create thumb column by defining thumb() and by assigning thumb() to list_display as shown below:
# "admin.py"
from django.contrib import admin
from .models import Site
from django.utils.html import format_html
#admin.register(Site)
class SiteAdmin(admin.ModelAdmin):
list_display = (
'is_active',
'name',
'description',
'keywords',
'date',
'thumb' # Here
)
# ...
def thumb(self, obj): # Here
return format_html(
f'''<a href="{obj.get_thumb()}" target="_blank">
<img
src="{obj.get_thumb()}" alt="{obj.get_thumb()}"
width="50" height="50"
style="object-fit: cover;"
/>
</a>''')
I have defined such a relation between questions and tags : (is this correct?)
myproject/myapp/models.py :
from django.db import models
from django.contrib.auth.models import User
from vote.managers import VotableManager
from django.utils import timezone
from datetime import datetime, timedelta
class Tag(models.Model):
text = models.CharField(max_length = 20)
user = models.ForeignKey(User)
class Question(models.Model):
text = models.TextField()
user = models.ForeignKey(User) # First writer of the question
tags = models.ManyToManyField(Tag)
votes = VotableManager()
created = models.DateTimeField(auto_now_add=True) # auto_now_add=True
modified = models.DateTimeField(auto_now=True) # auto_now=True
def was_published_recently(self):
return self.pub_date >= timezone.now() - timedelta(days=1)
and I want an admin page to create Questions, as well as Tags, so this is my admin.py:
from django.contrib import admin
from qportal.models import Tag, Question
class TagsInline(admin.TabularInline):
model = Question.tags.through
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['text']}),
#('Date information', {'fields': ['created'], 'classes': ['collapse']}),
]
inlines = [TagsInline]
list_display = ('text', 'created', 'was_published_recently')
list_filter = ['created']
search_fields = ['text']
admin.site.register(Question, QuestionAdmin)
however, when I run runserver and login to http://127.0.0.1:8000/admin/qportal/question/add/, the page I see is this :
As you can see, it only allows me to select a pre-existing tag. However I want to be able to create a tag for the first time, while creating the question, inline. How can I do that?
Thanks !
Don't use the inline for the tags. Regular M2M field will work in admin just fine. For more adequate M2M widget add the filter_horizontal property:
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['text', 'tags']}),
]
filter_horizontal = ['tags']
...
To create a Tag from the QuestionAdmin press the green + sign at the right side of the widget.
I've been trying to display a GenericForeignKey in the Django admin but can't get it working. I have a FullCitation class that can be linked to either a NonSupportedProgram or a SupportedProgram class. So, I have used a generic foreign key.
In the admin, I want users to only be able to select 'NonSupportedProgram' or 'SupportedProgram' from the content_type dropdown and then, from the object_id field, I need users to be able to select from a dropdown listing the existing NonSuportedPrograms or the existing SupportedPrograms, with the option of creating a new one. Is this possible? Where am I going wrong?
models.py
class FullCitation(models.Model)
# the software to which this citation belongs
# either a supported software program or a non-supported software program
limit = models.Q(app_label = 'myprograms', model = 'supportedprogram') | models.Q(app_label = 'myprograms', model = 'nonsupportedprogram')
content_type = models.ForeignKey(ContentType), limit_choices_to = limit, )
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
is_primary = models.BooleanField(help_text="Is this the Primary Citation for the software program?")
class Meta:
unique_together = ('content_type', 'object_id')
app_label = 'myprograms'
reversion.register(FullCitation)
class NonSupportedProgram(models.Model):
title = models.CharField(max_length=256, blank = True)
full_citation = generic.GenericRelation('FullCitation')
class Meta:
app_label = 'myprograms'
reversion.register(NonSBGridProgram)
class SupportedProgram(models.Model):
title = models.CharField(max_length=256, blank = True)
full_citation = generic.GenericRelation('FullCitation')
# and a bunch of other fields.....
admin.py
class FullCitationAdmin(reversion.VersionAdmin):
fieldsets = (
('Which Program', {
'fields': ('content_type', 'object_id', ),
}),
('Citation Information', {
'fields': ('is_primary',),
}),)
# autocomplete_lookup_fields = {
# 'generic': [['content_type', 'object_id']],
# }
# inlines = ['NonSupportedProgramInline', ]
list_display = ('content_object', 'is_primary',)
search_fields = ('content_object__title', )
# list_filter = ('content_object',)
This is a module that renders GenericForeignKeys in the Django Admin:
https://github.com/lexich/genericrelationview
It just doesn't work with a no conflict jQuery setup (like the one from Django CMS).