I'm starting a project in django 4.1. and I run into this problem:
many to many relationship: I have a field of this type that is required, and everything is fine, but when I use the filter_horizontal it does not let me insert the chosen value, it tells me that it is required, however I am selecting values
Admin.py:
from django.contrib import admin
from .models import *
from django.contrib.auth.models import User
class CatalejoAdmin(admin.ModelAdmin):
filter_horizontal = ('tematicas',)
admin.site.register(Catalejo, CatalejoAdmin)
admin.site.register(Tematicas)
Model:
from django.db import models
from django.contrib.auth.models import User
class Tematicas(models.Model):
tematica = models.CharField(max_length=500)
fecha = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User,null=True , default=User, editable=False, on_delete=models.DO_NOTHING)
class Meta:
ordering = ["tematica"]
verbose_name_plural = "Temática"
def __str__(self):
return self.tematica
class Catalejo(models.Model):
fecha = models.DateField()
titulo = models.CharField(max_length=500)
tematicas = models.ManyToManyField(Tematicas, related_name='Temáticas')
author = models.ForeignKey(User,null=True , default=User, editable=False, on_delete=models.DO_NOTHING)
fichero = models.FileField(upload_to='gestores/%Y/%m/%d', null=True, blank=True)
class Meta:
ordering = ["fecha"]
verbose_name_plural = "Catalejo"
def Tematicas(self):
return ",\n".join([p.tematica for p in self.tematicas.all()])
def dehydrate_full_title(self, Tematicas):
return '%s by %s' % (Tematicas.tematica)
enter image description here
I'm pretty new at Django and am stuck trying to implement Django import-export. My three pertinent model are Officer, Incident, and Details. Officer and Incident are in a M2M relationship through Details. I have gotten all of the functionality to work besides importing details. When I try to import via the import button, I get "NOT NULL constraint failed: police_archive_details.incident_id" for each row in the .xls or .csv file I'm importing.
Here's my (current) admin.py
from django.contrib import admin
from import_export import resources, widgets, fields
from import_export.admin import ImportExportModelAdmin, ImportExportActionModelAdmin
from forms import AdminTextForm, OfficerTextForm
from .models import Officer, Incident, Details, SiteText
class FullNameForeignKeyWidget(widgets.ForeignKeyWidget):
def get_queryset(self, value, row):
return self.model.objects.filter(
first_name__iexact=row["first_name"],
last_name__iexact=row["last_name"]
)
class DetailsInlineAdmin (admin.TabularInline):
model = Details
extra = 5
class OfficerResource(resources.ModelResource):
class Meta:
model = Officer
class OfficerAdmin(ImportExportModelAdmin):
list_display = ('first_name', 'last_name', 'badge', 'department')
search_fields = ['first_name', 'last_name']
inlines = [DetailsInlineAdmin]
resource_class = OfficerResource
form=OfficerTextForm
class Media:
js = ('//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js','/static/admin/js/admin/popup.js')
class IncidentResource(resources.ModelResource):
officer = fields.Field(
column_name='officer',
attribute='officer',
widget=widgets.ForeignKeyWidget(Officer, 'badge'))
class Meta:
fields = ('officer',)
model = Incident
class IncidentAdmin(ImportExportModelAdmin):
list_display = ('office','case_number')
search_fields = ['case_number']
inlines = [DetailsInlineAdmin]
resource_class = IncidentResource
class DetailsResource(resources.ModelResource):
officer = fields.Field(
column_name='officer',
attribute='officer',
widget=FullNameForeignKeyWidget(Officer))
incident = fields.Field(
column_name='incident',
attribute='incident',
widget=widgets.ForeignKeyWidget(Incident, 'case_number'))
class Meta:
fields = ('id','incident','officer__last_name','officer__first_name','allegation', 'finding', 'action')
model = Details
class DetailsAdmin(ImportExportModelAdmin):
list_display=('incident','officer', 'allegation', 'finding', 'action')
search_fields = ['officer__last_name', 'incident__case_number']
resource_class = DetailsResource
class SiteTextAdmin(admin.ModelAdmin):
form=AdminTextForm
admin.site.register(Officer, OfficerAdmin)
admin.site.register(Incident, IncidentAdmin)
admin.site.register(Details, DetailsAdmin)
admin.site.register(SiteText, SiteTextAdmin)
And here's models.py
from __future__ import unicode_literals
from django.db import models
from tinymce import models as tinymce_models
class Officer(models.Model):
first_name = models.CharField(max_length=80, blank=True, null=True)
last_name = models.CharField(max_length=80, blank=True, null=True)
badge = models.IntegerField(blank=True, null=True)
department = models.CharField(max_length=50, blank=True, null=True)
model_pic = models.ImageField(upload_to = "police_archive/officer_photos", default= 'noimage', blank=True, null=True)
description = tinymce_models.HTMLField(blank=True, null=True)
def __str__(self):
return self.last_name + ', ' + self.first_name
class Meta():
ordering = ['last_name']
class Incident(models.Model):
officer = models.ManyToManyField(Officer, through='Details')
case_number = models.CharField(max_length=50, blank=True)
OFFICE_CHOICES = (
('CRA', 'Civilian Review Authority'),
('IA', 'Internal Affairs'),
('OPCR', 'Office of Police Conduct Review'),
)
office = models.CharField(max_length=10,
choices=OFFICE_CHOICES,
)
def __str__(self):
return self.case_number
class Meta():
ordering = ['-case_number']
class Details(models.Model):
officer = models.ForeignKey(Officer, on_delete=models.CASCADE, blank=True)
incident = models.ForeignKey(Incident, on_delete=models.CASCADE, blank=True)
allegation = models.CharField(max_length=50, blank=True)
finding = models.CharField(max_length=50, blank=True)
action = models.CharField(max_length=50, blank=True)
def __str__(self):
return self.officer.first_name + ' '+ self.officer.last_name+ ', ' + self.incident.case_number
class Meta():
verbose_name_plural = "details"
ordering = ['incident__case_number']
class SiteText(models.Model):
content1 = tinymce_models.HTMLField()
content2 = models.TextField(max_length=500, blank=True)
OK, I spent all day debugging yesterday and got everything working properly. Here's my admin.py now, models.py is unchanged. I forget exactly which change solved the original error I posted about.
from django.contrib import admin
from import_export import resources, widgets, fields
from import_export.admin import ImportExportModelAdmin, ImportExportActionModelAdmin
from forms import AdminTextForm, OfficerTextForm
from .models import Officer, Incident, Details, SiteText
class DetailsInlineAdmin (admin.TabularInline):
model = Details
extra = 5
class OfficerResource(resources.ModelResource):
class Meta:
model = Officer
class OfficerAdmin(ImportExportModelAdmin):
list_display = ('first_name', 'last_name', 'badge', 'department')
search_fields = ['first_name', 'last_name']
inlines = [DetailsInlineAdmin]
resource_class = OfficerResource
form=OfficerTextForm
class Media:
js = ('//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js','/static/admin/js/admin/popup.js')
class IncidentResource(resources.ModelResource):
class Meta:
fields = ('officer','case_number', 'office')
model = Incident
import_id_fields = ['case_number']
class IncidentAdmin(ImportExportModelAdmin):
list_display = ('office','case_number')
search_fields = ['case_number']
inlines = [DetailsInlineAdmin]
resource_class = IncidentResource
class DetailsResource(resources.ModelResource):
class BadgeForeignKeyWidget(widgets.ForeignKeyWidget):
def get_queryset(self, value, row):
return self.model.objects.filter(
badge__iexact=row["badge"]
)
officer = fields.Field(
column_name='officer',
attribute='officer',
widget=BadgeForeignKeyWidget(Officer, 'last_name'))
incident = fields.Field(
column_name='incident',
attribute='incident',
widget=widgets.ForeignKeyWidget(Incident, 'case_number'))
class Meta:
fields = ('id','officer','incident', 'allegation', 'finding', 'action')
model = Details
class DetailsAdmin(ImportExportModelAdmin):
list_display=('incident','officer', 'allegation', 'finding', 'action')
search_fields = ['officer__last_name', 'incident__case_number']
resource_class = DetailsResource
class SiteTextAdmin(admin.ModelAdmin):
form=AdminTextForm
admin.site.register(Officer, OfficerAdmin)
admin.site.register(Incident, IncidentAdmin)
admin.site.register(Details, DetailsAdmin)
admin.site.register(SiteText, SiteTextAdmin)
Another note is that you need to put an 'id' column in your spreadsheet. I was able to leave mine blank and then Django would generate an id to use as a primary key.
I'm at a bit of a loss on how to correctly reference foreign key values when looking at the Admin page in Django 1.8.
What I am getting:
Note that the foreign key displays correctly in the left column, but not in the right (using for verification), nor does it show when you click into one of the records, which is where I require it to display.
What I want:
I want the second image to display 4147128 instead of WorldEaseConsignee object.
Code
admin.py
from django.contrib import admin
from .models import WorldEaseConsignee, WorldEaseInvoice
class WorldEaseConsigneeAdmin(admin.ModelAdmin):
list_display = (
'order_number',
)
class WorldEaseInvoiceAdmin(admin.ModelAdmin):
#staticmethod
def get_order_number(obj):
return obj.order_number.order_number
list_display = (
'get_order_number', 'order_number_id'
)
search_fields = [
'order_number__order_number',
]
admin.site.register(WorldEaseConsignee, WorldEaseConsigneeAdmin)
admin.site.register(WorldEaseInvoice, WorldEaseInvoiceAdmin)
models.py subset
class WorldEaseInvoice(models.Model):
class Meta:
verbose_name = 'WorldEase Invoice List'
verbose_name_plural = 'WorldEase Invoice List'
unique_together = ('order_line', 'order_number')
order_number = models.ForeignKey(
WorldEaseConsignee,
to_field='order_number',
)
def __unicode__(self):
return self.name
class WorldEaseConsignee(models.Model):
class Meta:
verbose_name = 'WorldEase Consignee List'
verbose_name_plural = 'WorldEase Consignee List'
order_number = models.IntegerField(
null=False,
blank=False,
default=0,
unique=True,
)
def __unicode__(self):
return self.order_number # I've also tried self.name
Since you are using Python 3, you should be defining __str__ methods instead of __unicode__.
There is a class named Employees in models.py
class Employees(models.Model):
employee_id = models.CharField(verbose_name = _("Employee ID"), max_length=20, primary_key=True)
employee_name = models.CharField(verbose_name = _("Employee Name"), max_length=20)
department = models.CharField(verbose_name = _("Department"), max_length=100)
post = models.CharField(verbose_name = _("Post"), max_length=100)
Then I wrote some code in admin.py
class EmployeesAdmin(admin.ModelAdmin):
list_display = ('employee_id', 'employee_name', 'department', 'post')
According to the tutorial, there should be four fields in the Employee branch. But in my situation, there is only one field named Employees, just like I didn't add EmployeesAdmin class in admin.py. What's wrong with it? Did I miss something?
admin.py:
from django.contrib import admin
from .models import Employees, Purchase, ProductsOut
# Register your models here.
admin.site.register(Employees)
admin.site.register(Purchase)
admin.site.register(ProductsOut)
Register your admin in admin.site like:-
admin.site.register(ModelName, AdminName)
Try the following after declaring your EmployeesAdmin class in admin.py:
admin.site.register(Employees, EmployeesAdmin)
I have this model in django
from django.db import models
class ProductType(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
type = models.ForeignKey(ProductType, related_name='product_type')
related_products = models.ManyToManyField('self',blank=True,null=True)
description = models.TextField()
def __unicode__(self):
return self.name
What I would like to do is in the admin have the Products as tabular inline to a quote page that have multiple products. This thing is that the first selected model can be a parent to the others and therefore I would like the choices of the next elements to be sorted by the first.
this is the quote model
from django.db import models
from django.utils.translation import ugettext as _
import datetime
from products.models import Product
from customers.models import Customer
class Quote(models.Model):
quoteid = models.IntegerField(_('Quote ID'), max_length=8, unique=True, default=number)
slug = models.SlugField(unique=True,default=number)
add_date = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey(Customer, related_name='quote_customer',blank = True, null = True)
product = models.ManyToManyField(Product, related_name='quote_product')
def __unicode__(self):
return str(self.quoteid)
and the admin part
from django.contrib import admin
from quotes.models import Quote
class ProductInline(admin.TabularInline):
model = Quote.product.through
extra = 3
class QuoteAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('quoteid',)}
fieldsets = (
(('Quote'), {'fields': ('slug','quoteid','customer',)}),
)
list_display = ('quoteid','customer','add_date',)
inlines = [ ProductInline]
admin.site.register(Quote,QuoteAdmin)
I know this is quite tricky and I have tried many ways but I have not found a solution that works. I have tried with formfield_for_manytomany but I can't fully grasp how to return the first tabularinline object as the input for the queryset.
If someone have a link that explains a method to do this I would be grateful.