Why are my django model fields not working? - python

I don't think that it is recognizing the existence of my fields. Here's my models.py:
from django.db.models import *
from django.contrib import admin
from django.forms import *
class Stock(Model):
name = CharField(max_length=60)
class Meta:
ordering = ["name"]
def __unicode__(self):
return self.name
admin.site.register(Stock)
When I run it, I get this error: "portfolio.stock: "ordering" refers to "name", a field that doesn't exist." When I comment the meta function out and run it, it works fine until the admin site, where when I try to create a stock object, the fields don't show up.
I'm completely confused by what's going on.

The problem is your * imports.
django.db.models.CharField is being replaced by django.forms.CharField:
>>> from django.db.models import *
>>> CharField
<class 'django.db.models.fields.CharField'>
>>> from django.forms import *
>>> CharField
<class 'django.forms.fields.CharField'>
So, actually name = CharField(max_length=60) defines a form field instead of a model one - it breaks everything and makes this bug subtle.
Solution: remove unnecessary forms import and be explicit in your imports:
from django.db import models
from django.contrib import admin
class Stock(models.Model):
name = models.CharField(max_length=60)
class Meta:
ordering = ["name"]
def __unicode__(self):
return self.name
admin.site.register(Stock)

Related

How to import auth.User on django-import/export

I can't import a CSV file into model on Django.
I made a column 'author' and put the superuser's id which I am login to the admin site.
But there was an error like this when I import the CSV file.
Line number: 1 - null value in column "author_id" violates not-null constraint DETAIL: Failing row contains (10, abc, blahblah, null, ).
5, abc, blahblah, , nah,wha,blah
csv file
author,title,text,file,free_tags
5,abc,blahblah,,"nah,wha,blah"
models.py
from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager
class KnowHow(models.Model):
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField(blank=True)
file = models.FileField(blank=True,upload_to='explicit_knowhows')
free_tags = TaggableManager(blank=True)
def __str__(self):
return self.title
admin.py
from django.contrib import admin
from import_export import resources
from import_export import fields
from import_export.admin import ImportExportModelAdmin
from .models import KnowHow
# Register your models here.
class KnowHowResource(resources.ModelResource):
class Meta:
model = KnowHow
exclude = 'id'
import_id_fields = ('title', )
#admin.register(KnowHow)
class knowHowAdmin(ImportExportModelAdmin):
resource_class = KnowHowResource
The error says that author_id is missed.
Django adds a postfix to all the ForeignKey fields, so you should try to modify the file renaming the column:
author_id,title,text,file,free_tags
5,abc,blahblah,,"nah,wha,blah"
It fixed when I saved the CSV by encoding in UTF-8. This will not support non-alphabet letter so I recommend using .xlsx file instead.
Thank you to everyone who tried to fix my problem.

lack of foreign key in admin model?

I get the following error when trying to update my database:
class 'artdb.admin.RoleInline': (admin.E202) 'artdb.Role' has no ForeignKey to 'artdb.Person'
I want ot have a many to many relation between Person and Role
model.py (not showing all classes):
class Person(models.Model):
mail=models.EmailField()
firstName=models.CharField(max_length=200)
lastName=models.CharField(max_length=200)
phoneNumber=PhoneNumberField()
streetAdress=models.CharField(max_length=200)
zipcode=models.CharField(max_length=200)
city=models.CharField(max_length=200,default="Göteborg")
country=models.CharField(max_length=200,default="Sweden")
def __str__(self):
return "%s %s" % (self.firstName,self.lastName)
class Meta:
ordering = ('firstName','lastName')
class Role(models.Model):
role=models.CharField(max_length=200)
person=models.ManyToManyField(Person)
def __str__(self):
return self.role
class Meta:
ordering = ('role',)
admin.py (not showing all classes):
from django.contrib import admin
from .models import Role
from .models import Address
from .models import Date
from .models import Person
from .models import Name
# Register your models here.
admin.site.register(Role)
admin.site.register(Address)
admin.site.register(Date)
admin.site.register(Name)
admin.site.register(Person)
class RoleInline(admin.TabularInline):
model=Role
extra=3
class PersonInline(admin.ModelAdmin):
fieldsets=[
(None,{'fields': ['mail','firstName','lastName','phoneNumber','streetAdress','zipcode','city','country']}),
]
inlines = [RoleInline]
search_fields = ['firstName']
#admin.site.register(Name,NameInline)
admin.site.register(Person,PersonInline)
it has worked before with run manage.py makemigrations artdb
I don't see the errorin the models.
You are having wrong model for RoleInline as per documentation for ManytoMany relationship in TabularInline
model = Role.persons.through
You need to use model=Role.person.through instead of model=Role as shown below:
class RoleInline(admin.TabularInline):
# model=Role
model=Role.person.through # Here
extra=3

django-image-cropping not working

Trying to use django-image-cropping. I don't get any errors, I just have what looks like CharField in Django Admin instead of the django-image-cropping functionality:
base.py (settings):
from easy_thumbnails.conf import Settings as thumbnail_settings
THUMBNAIL_PROCESSORS = (
'image_cropping.thumbnail_processors.crop_corners',
) + thumbnail_settings.THUMBNAIL_PROCESSORS
added easy_thumbnails and image_cropping to INSTALLED_APPS
models.py:
from image_cropping import ImageRatioField
# ...
class Organization(models.Model):
image_cover = models.ImageField(upload_to='media', blank=True, help_text="blah")
cropping = ImageRatioField('image_cover', '308x850')
admin.py:
from django.contrib import admin
from image_cropping import ImageCroppingMixin
class OrganizationAdmin(ImageCroppingMixin, admin.ModelAdmin):
pass
class OrganizationAdmin(admin.ModelAdmin):
filter_horizontal=['categorys']
#...
admin.site.register(Organization, OrganizationAdmin)
You're defining OrganizationAdmin twice in admin.py. Once, correctly, subclassing ImageCroppingMixin and once without. Since the latter definition overwrites the former, you end up without the Mixin. This is how it should look like:
from django.contrib import admin
from image_cropping import ImageCroppingMixin
class OrganizationAdmin(ImageCroppingMixin, admin.ModelAdmin):
filter_horizontal=['categorys']
#...
admin.site.register(Organization, OrganizationAdmin)

Django ModelAdmin extra input field not from Model

I'm trying to add an extra input to a admin.ModelAdmin for a model I have so I can record some optional text when another input has changed.
I can't get the custom ModelForm recognised as name 'EquipmentAdmin' is not defined. I've tried several different ways of importing but think I must have missed something obvious. It feels like there's a circular reference between the EquipmentAdmin and EquipmentAdminForm as they both include a reference to each other in the code.
I have created my Django application Flightdeck and have these all in the same folder;
models.py
from django.db import models
class Location(models.Model):
name = models.CharField(max_length=45)
class Equipment(models.Model):
unit_id = models.CharField(max_length=45)
located = models.ForeignKey(Location)
located_from = models.DateField()
class EquipmentLocationHistory(models.Model):
unit = models.ForeignKey(Equipment)
located = models.ForeignKey(Location)
start = models.DateField()
end = models.DateField()
change_reason = models.CharField(max_length=45)
admin.py
from django.contrib import admin
from flightdeck.models import *
from flightdeck.forms import EquipmentAdminForm
class EquipmentAdmin(admin.ModelAdmin):
form = EquipmentAdminForm
def save_model(self, request, obj, form, change):
if 'located' in form.changed_data:
try:
old = Equipment.objects.get(unit_id=obj.unit_id)
except Equipment.DoesNotExist:
old = None
if old:
if 'located' in form.changed_data:
located_history = EquipmentLocationHistory(unit=obj, located=old.located, start=old.located_from, end=obj.located_from)
located_history.save()
obj.save()
forms.py
from django import forms
from django.contrib import admin
class EquipmentAdminForm(forms.ModelForm):
reason = forms.CharField()
class Meta:
model = EquipmentAdmin
I would like to include the reason value when I add the EquipmentLocationHistory but can't test what I have as the EquipmentAdminForm isn't loaded.
EquipmentAdmin is not a model. Your ModelForm needs to reference Equipment
from django import forms
from django.contrib import admin
from flightdeck.models import Equipment
class EquipmentAdminForm(forms.ModelForm):
reason = forms.CharField()
class Meta:
model = Equipment
PS: when you have circular references, there are many ways around the problem. The best way with model imports and django is to use django.db.models.get_model('app', 'model')

Require model field in admin site only if another model field is true

In one of my models, I want a foreign key object to be required only if another boolean model field is true. How do I configure the admin site to behave this way?
My models.py contains:
from django.db import models
class ThingOne(models.Model):
name = models.CharField(max_length=100)
class ThingTwo(models.Model):
name = models.CharField(max_length=100)
use_thingone = models.BooleanField()
thingone = models.ForeignKey(ThingOne, blank=True, null=True)
And my admin.py contains:
from myapp.models import ThingOne
from myapp.models import ThingTwo
from django.contrib import admin
admin.site.register(ThingOne)
admin.site.register(ThingTwo)
How do I adjust this to make thingone a required foreign key field only if use_thingone is true?
You actually only need to override your model's clean method:
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.db import models
class ThingTwo(models.Model):
#Your stuff
def clean(self):
"""
Validate custom constraints
"""
if self.use_thingone and self.thingone is None:
raise ValidationError(_(u"Thing One is to be used, but it not set!"))
Create form for the ThingTwo and check what you need in model's clean() method.
Here are creating form for model - https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelform and using custom form for model admin - https://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin

Categories

Resources