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).
Related
i'm developing a django site deployed via Nginx and PostgreSQL.
I did some changes to my models.py and admin.py pages to correct a field.
Yet this change is not being shown in my Django admin page, it's still with the old field names regardless of the change in my models.py folder.
Here's the models.py and admin.py sections of code
models.py
title = models.CharField(max_length=100, help_text="Titulo del Proyecto", verbose_name="Titulo")
subtitle = models.CharField(max_length=100, help_text="Subtitulo", verbose_name="Subtitulo")
image = models.ImageField(upload_to='media/images',blank=True, help_text="Imagen del Proyecto", verbose_name="Imagen")
slug = models.SlugField(max_length=100, help_text="No tocar", verbose_name="Slug")
description = models.TextField(help_text="Descripcion del Proyecto", verbose_name="Descripcion")
date = models.DateField()
video_url = models.CharField(max_length=200, blank=True,help_text='Url del video ', verbose_name='Video URL')
source = models.ForeignKey('Source', on_delete=models.CASCADE,blank=True, help_text='Youtube o Vimeo o NONE si no hay video',verbose_name='Source')
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True, help_text='Categoria del projecto', verbose_name='Categoria')
admin.py
class ProjectAdmin(admin.ModelAdmin):
pass
list_display = ('title', 'date', 'category', 'source')
list_filter = ('date', 'category', 'source')
search_fields = ('title', 'description')
ordering = ['-date', 'title']
date_hierarchy = 'date'
fieldsets = (
(None, {
'fields': ('title','subtitle', 'description', 'image', 'date', 'video_url', 'source', 'category', 'slug')
}),
)
prepopulated_fields = {'slug': ('title',)}
Please check you question, your code is not completely there, or it from different project: for example, label in model for category is "Categoria", field label on the admin panel is "Catégorle".
I can imagine, that you work with lazy translations. In this case you should change translations for 'label' and 'help_text' and not to do something with models.
Other case is, you Admin form is overridden. There you can change labels and help text too.
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']
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
Hi i would like to make primary key as visible when viewing or modifying the records. But it should not be editable in django admin page. Hence i tried readonly_fields. How ever when i give read only, I am not able enter primary key value when i add new record.
Here is my admin.py
class EmployeeAdmin(admin.ModelAdmin):
search_fields = ['name']
list_display = ('name','id','dob','bill','mobile','email')
list_filter = ('bill','proj')
readonly_fields=('id',)
My model.py is ,
class Employee(models.Model):
id = models.IntegerField(max_length = 6,primary_key=True)
name = models.CharField(max_length = 100)
dob = models.DateField(verbose_name='Date Of Birth')
doj = models.DateField(verbose_name='Date Of Joining')
Your class in admin.py should be like below. Please use get_readonly_fields to do this.
class EmployeeAdmin(admin.ModelAdmin):
search_fields = ['name']
list_display = ('name','id','dob','bill','mobile','email')
list_filter = ('bill','proj')
# readonly_fields=('id',)
def get_readonly_fields(self, request, obj=None):
if obj: # editing an existing object
return self.readonly_fields + ('id',)
return self.readonly_fields
I have two models:
class Organization(models.Model):
name = models.CharField(max_length=64)
class OrgUser(User):
organization = models.ForeignKey(Organization, related_name='users')
role = models.CharField(max_length=1, choices=USER_TYPE_CHOICES)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role', 'organization',)
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
users = USerSerializer(many=True)
class Meta:
model = Organization
depth = 1
fields = ('name', 'users',)
I'm using the Django REST Framework and I'm trying to get the following output for the given URLS:
GET /organization/
{
'name':'Hello World',
'users':[{ 'email':'test#gmail.com', 'role':'A' }]
}
GET /user/
{
'email':'test#gmail.com',
'role':'A',
'organization':{ 'name':'Hello World' }
}
So what's happening is GET /organization/ is giving me the users array and the organization information again.
I've been racking my brain setting the depth property on my serializer, but I can't figure it out for the life of me. If someone could please point me in the right direction, I'd greatly appreciate it.
The problem is that you want different output from your UserSerializer depending on if it's being used alone (i.e. at GET /user/) or as a nested relation (i.e. at GET /organization/).
Assuming you want different fields in both, you could just create a third Serializer to use for the nested relationship that only includes the fields you want in the OrganizationSerializer. This may not be the most elegant way to do it, but I can't find any alternatives.
Sample code:
class Organization(models.Model):
name = models.CharField(max_length=64)
class OrgUser(User):
organization = models.ForeignKey(Organization, related_name='users')
role = models.CharField(max_length=1, choices=USER_TYPE_CHOICES)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role', 'organization',)
class OrganizationUserSerializer(serializers.HyperlinkedModelSerializer): # New Serializer
class Meta:
model = OrgUser
depth = 1
fields = ('email', 'role',)
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
users = OrganizationUserSerializer(many=True) # Change to new serializer
class Meta:
model = Organization
depth = 1
fields = ('name', 'users',)