Unable to delete object from Django admin panel with MongoDB - python

I have a Django project using a MongoDB connected by Djongo. I created a simple model which looks like:
from django.db import models
# Create your models here.
class Property(models.Model):
name = models.CharField(max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)
After registering the model by using the line admin.site.register(Property) in the admin.py file I end up seeing my model appear. After adding a test Property I see the line
The property “Property object (61226db9f4f416b206c706e5)” was added successfully.
Which tells me the item was added. It also appears on the admin panel but it looks like:
Property object (None)
If I select the property I get an error that says:
Property with ID “None” doesn’t exist. Perhaps it was deleted?
If I try to delete the property I get a ValueError with error of:
Field 'id' expected a number but got 'None'.
Since I am currently learning Django/MongoDB I actually ran across the ValueError once before. The fix was to delete the entire database and start over. The issue is I don't want to run into this in the future and want to know what I have to do to fix it, or correct what I am doing wrong.

I found my answer. Turns out I need to assign a primary key. I fixed this by changing my model to..
class Property(models.Model):
name = models.CharField(primary_key=True, max_length=128, blank=False)
property_type = models.CharField(max_length=24, blank=True)
include_on = models.CharField(max_length=256, blank=True)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)

Related

Django psycopg2.errors.StringDataRightTruncation: value too long for type character varying(200)

Facing the above error when running the django app. What exactly needs to be changed though?
The comment_body = models.TextField() aspect most probably is the culprit since it stores reddit comments which can be of varying lengths. When i do a git clone and run it on my local, strangely it works.
Models.py
from django.db import models
# Create your models here.
class Subreddit(models.Model):
# Field for storing the name of a subreddit
subreddit_name = models.CharField(max_length=200, unique=True)
# Field for storing the time the model object was last saved
last_updated = models.DateTimeField(auto_now=True)
class Submission(models.Model):
subreddit = models.ForeignKey(Subreddit, on_delete=models.CASCADE)
# The Reddit submission id of the object
submission_id = models.CharField(max_length=200, unique=True)
# Reddit Submission URL
url = models.URLField(max_length=200)
# Reddit Submission Title
title = models.CharField(max_length=200)
class SubmissionComment(models.Model):
# Parent submission object
submission = models.ForeignKey(Submission, on_delete=models.CASCADE)
# Text of the comment
comment_body = models.TextField()
class Meme(models.Model):
memeurl = models.URLField(max_length=200)
EDIT:
New error post char changed to 300, and migrations run locally and on heroku.
Given the error: value too long for type character varying(200) you should look for model fields that have a max_length of 200. Since you have multiple fields with a max_length set to 200, you need to determine which model and field are throwing the error. Check the stacktrace, run a debugger and/or insert some debugging print(instance.__dict__)s. Once you find the culprit, extend that field's max_length to something larger or turn it into a TextField.

Using Model.objects.all() as a blueprint for a secondary table entry

I am having a bit of trouble with the logic of how this should work so I am hoping it is possible.
I figured out 1 possible solution that is written as an answer below, I will accept it in a few days, but if someone comes up with a better solution, I will negate any answer I post.
Overall I am working on an Apartment Move-Out/Move-In Inspection Application in Django, and in both portions I have universal Locations that must be inspected for each report. I have allowed the InspectionLocations objects to be updated/submitted by clients, which is presenting an issue in how submitted reports should be stored in my Database.
What I want is to use the InspectionLocations table as a blueprint to build an Inspection Report for Move-Ins where the form-fields are generated based on the InspectionLocations objects' location, status, and information attributes/fields.
My issue is right at this point, how do I reference those values as a blueprint to build a report submission when the number of fields in the InspectionLocations can change?
from django.db import models
from apps.units.models import Unit
class Inspections(models.Model):
class Meta:
abstract = True
id = models.AutoField(primary_key=True)
inspection_date = models.DateField()
submitted_by = models.ForeignKey(
'users.CustomUser',
default=None,
null=True,
on_delete=models.SET_NULL,
db_column='submitted_by')
last_update = models.DateTimeField(auto_now=True)
date_added = models.DateTimeField(auto_now_add=True, editable=False)
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
# should have reference to all InspectionLocation items as reference for submission, how?
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
# should have reference to all InspectionLocation items as reference for submission, how?
class InspectionLocations(models.Model):
'''
Defualt Inspection Locations are created when a
client is created using code like this:
InspectionLocation.objects.get_or_create(location='Living Room')
InspectionLocation.objects.get_or_create(location='Dining Room')
InspectionLocation.objects.get_or_create(location='Kitchen')
InspectionLocation.objects.get_or_create(location='Bedroom')
InspectionLocation.objects.get_or_create(location='Bathroom')
InspectionLocation.objects.get_or_create(location='Other')
'''
id = models.AutoField(primary_key=True)
location = models.CharField(max_length=50)
status = models.BooleanField(default=None)
information = models.TextField(default=None, blank=True)
I have tried ManyToMany fields and FKs but I cannot seem to get the logic working as anytime an object references an InspectionLocations object it is universally changing data for every report, which is leading be to the idea that I somehow need to use it as a blueprint.
I didn't post this in my question because it was getting long, but my best option so far seems to be to use a Django JSONField (as I am using Postgres), like so:
from django.contrib.postgres.fields import JSONField
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
data = JSONField()
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
data = JSONField()
To where I store the values of the InspectionLocations object's in a Dictionary

models clash with (META) inheritance

in a django project i' ve multiple apps, and the common contains the following models:
class CLDate(models.Model):
class Meta:
abstract = True
active = models.BooleanField(default=True)
last_modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Switch(CLDate):
name = models.CharField(max_length=64)
code = models.CharField(max_length=64, blank=True, null=True)
description = models.TextField(blank=True, null=True)
sorted = models.IntegerField(default=0)
class Currency(Switch):
pass
In another application i import the Switch, and try to add a ForeignKey to a model which inherits also from Switch
class Country(Switch):
...
currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
...
.
Running makemigration or anything with manage.py i get the following error:
SystemCheckError: System check identified some issues:
ERRORS:
ads.Country.currency: (models.E006) The field 'currency' clashes with the
field 'currency' from model 'common.switch'.
Why do i get this error, and how could i resolve it? I mean, at the database level it should be only a "pointer" to the currency Model / object, and should be irrelevant to its type. Of course if i change the inheritance type of the Currency to something else, it works fine.
Django: 2.2
python: 3.5.3
.

Django - get_or_create() with auto_now=True

I’m using Django and I'm having a problem with a Python script that uses Django models
The script that I'm using takes data from an api and loads it into my database.
my model:
class Movie(models.Model):
title = models.CharField(max_length=511)
tmdb_id = models.IntegerField(null=True, blank=True)
release = models.DateField(null=True, blank=True)
poster = models.TextField(max_length=500, null=True)
runtime = models.IntegerField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
edit = models.DateTimeField(auto_now=True, null=True, blank=True)
backdrop = models.TextField(max_length=500, null=True, blank=True)
popularity = models.TextField(null=True, blank=True)
the script:
movies = tmdb.Movies().upcoming()
results = movies['results']
ids = []
for movie in results:
data, created = Movie.objects.get_or_create(title=movie['title'],
tmdb_id=movie['id'],
release=movie['release_date'],
description=movie['overview'],
backdrop=movie['backdrop_path'],
poster=movie['poster_path'],
popularity=movie['popularity'])
The problem I'm having is that whenever I run the script, the entries are duplicated because the edit field is change, but the purpose I put the edit field is to know when exactly a movie got edited, ie: some other field got changed.
How can I avoid the duplicates, but also keep the edit field in case some real change happened?
but the purpose I put the edit field is to know when exactly a movie
got edited, ie: some other field got changed.
That probably means you are using the wrong function. You should be using update_or_create istead.
A convenience method for updating an object with the given kwargs,
creating a new one if necessary. The defaults is a dictionary of
(field, value) pairs used to update the object.
This is different from get_or_create, which creates an object if it does not exists, or simply fetches it when it does exist. update_or_create is the one that does the actually updating.
However, changing to this method doesn't solve this:
How can I avoid the duplicates, but also keep the edit field in case
some real change happened?
Duplicates are created because you do not have a unique index on any of your fields. Both get_or_create and update_or_create require that you have a unique field. It seems that the following change is in order:
class Movie(models.Model):
title = models.CharField(max_length=511)
tmdb_id = models.IntegerField(unique=True)

FieldError: Cannot resolve keyword 'XXXX' into field

This is a very strange error. I only receive it on my heroku server.
Here is how my model is:
# Abstract Model
class CommonInfo(models.Model):
active = models.BooleanField('Enabled?', default=False)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Country(CommonInfo):
name = models.CharField('Country Name', db_index=True, max_length=200, help_text='e.g. France')
official_name = models.CharField('Official Name', max_length=400, blank=True, help_text='e.g. French Republic')
population = models.IntegerField('Population', help_text='Population must be entered as numbers with no commas or separators, e.g. 39456123', null=True, blank=True)
alpha2 = models.CharField('ISO ALPHA-2 Code', max_length=2, blank=True)
class News(CommonInfo):
title = models.CharField('Title', max_length=250)
slug = models.CharField('slug', max_length=255, unique=True)
body = models.TextField('Body', null=True, blank=True)
excerpt = models.TextField('Excerpt', null=True, blank=True)
author = models.ForeignKey(Author)
country = models.ManyToManyField(Country, null=True, blank=True)
def __unicode__(self):
return self.title
When I try to access News items from Admin site on my production server, I get this error (everything works fine on my dev server):
FieldError: Cannot resolve keyword 'news' into field. Choices are: active, alpha2, date_created, date_updated, id, name, official_name, population
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/query.py", line 687, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1271, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1139, in add_filter
process_extras=process_extras)
File "/app/.heroku/python/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1337, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
I run the same django (1.5.4) and python (2.7.2) versions on my production and development environments.
My production server is Heroku
Any ideas what could triggers the error?
UPDATE:
admin.py config is as follow:
from django.contrib import admin
from APP.models import Country, News
class NewsForm(ModelForm):
class Meta:
model = News
class NewsAdmin(ModelAdmin):
form = NewsForm
search_fields = ['title',
'country__name']
list_filter = ('country',
'active'
)
list_per_page = 30
list_editable = ('active', )
list_display = ('title',
'active'
)
list_select_related = True
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Country)
admin.site.register(News, NewsAdmin)
Finally, I was able to resolve the issue.
First, I managed to replicate the error in my local environment. At first, I was testing the application using built-in Django runserver. However, my production environment is Heroku that uses Gunicorn as webserver. When I switched to Gunicorn and foreman on my local server, I was able to replicate the error.
Second, I tried to pin point the issue by going through the models and add/remove different components, fields. To explain the process better, I have to add a missing piece to the original question.
The description I had posted above is kind of incomplete. I have another model in my models.py that I did not include in my original question, because I thought it was not relevant. Here is the complete model:
# Abstract Model
class CommonInfo(models.Model):
active = models.BooleanField('Enabled?', default=False)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Country(CommonInfo):
name = models.CharField('Country Name', db_index=True, max_length=200, help_text='e.g. France')
official_name = models.CharField('Official Name', max_length=400, blank=True, help_text='e.g. French Republic')
population = models.IntegerField('Population', help_text='Population must be entered as numbers with no commas or separators, e.g. 39456123', null=True, blank=True)
alpha2 = models.CharField('ISO ALPHA-2 Code', max_length=2, blank=True)
def get_country_names():
names = Country.objects.only('name').filter(active=1)
names = [(str(item), item) for item in names]
return names
class Person(CommonInfo):
name = models.CharField(max_length=200)
lastname = models.CharField(max_length=300)
country = models.CharField(max_length=250, choices=choices=get_country_names())
class News(CommonInfo):
title = models.CharField('Title', max_length=250)
slug = models.CharField('slug', max_length=255, unique=True)
body = models.TextField('Body', null=True, blank=True)
excerpt = models.TextField('Excerpt', null=True, blank=True)
author = models.ForeignKey(Author)
country = models.ManyToManyField(Country, null=True, blank=True)
def __unicode__(self):
return self.title
My model design didn't require a ForeignKey for Person's table, so I had decided to go with a simple CharField and instead, use a regular drop down menu. However, for some reason, Gunicorn raises the above mentioned error when, as part of the get_country_names(), the Country table is called before News. As soon as I deleted the get_country_names() and turned the country field on Person table into a regular CharField the issue was resolved.
Reading through the comments in this old Django bug and this post by Chase Seibert considerably helped me in this process.
Although ticket#1796 appears to be fixed more than 6 years ago, it seems that some tiny issues still remain deep buried there.
Thats it! Thanks everyone.
Adding to the possible situations under which this happens. I searched for the field that could not be found in any of my models.
Searching on the code I found that I was annotating a queryset with such field and then feeding that queryset as an __in search to another (along other complex queries).
My work around was to change that annotated queryset to return IDs and use that. On this particular case that result was always going to be small so the list of IDs was not a problem to pass.
I'd had some ManyToMany relationships that were working one-way. I had been messing around with my settings and changing the name of the main application a couple times. Somewhere along the lines, I had removed it from the INSTALLED_APPS section! Once I added that back in, then it worked. Definitely PEBKAC, but maybe this will help someone some day. It took me a while to think of checking for that, since the app was mostly working.
For example, my app is called deathvalleydogs. I had two models:
class Trip(ModelBase):
dogs = models.ManyToManyField(Dog, related_name="trips")
class Dog(ModelBase):
name = models.CharField(max_length=200)
when I tried to show a template for a Trip listing the Dogs that were on the trip like this:
{% for dog in trip.dogs.all %}
<li>{{ dog.name }}</li>
{% endfor %}
then I got an error of:
Cannot resolve keyword u'trips' into field. Choices are: active, birth_date, ...
Though I was still able to show a template for a Dog listing the trips they were on. Notice that trips should have been a field created by the m2m on the Dog objects. I wasn't referencing that field in the template, but it barfed on that field anyway in debug mode.
I wish the error had been more explicit, but I'm just so happy I finally found my mistake!!!
You can try to reset migrations:
Remove the all migrations files within your project.
Go through each of your projects apps migration folder (your_app/migrations/) and remove everything inside, except the init.py file.
Run makemigrations and migrate.
I was using the wrong dunder lookup on an admin model search field, so for example:
Not working:
class SomeAdmin(admin.ModelAdmin):
list_display = (
"id",
"thing_id",
"count",
"stuff_name",
"stuff_id"
)
readonly_fields = ("count")
# These cannot be resolved, because "stuff" doesn't exist on the model
search_fields = ("stuff__name", "stuff__id")
def stuff_name(self, obj):
return obj.thing.stuff.name
def stuff_id(self, obj):
return obj.thing.stuff.id
def get_queryset(self, request):
return super().get_queryset(request).select_related("thing")
Working:
class SomeAdmin(admin.ModelAdmin):
list_display = (
"id",
"thing_id",
"count",
"stuff_name",
"stuff_id"
)
readonly_fields = ("count")
search_fields = ("thing__stuff__name", "thing__stuff__id", "thing__id")
def stuff_name(self, obj):
return obj.thing.stuff.name
def stuff_id(self, obj):
return obj.thing.stuff.id
def get_queryset(self, request):
return super().get_queryset(request).select_related("thing")
I had this error. And if your are using POSTMAN to do an API call to a URL, then you may be encountering this same error.
django.core.exceptions.FieldError: Cannot resolve keyword 'player' into field. Choices are ...
Either in your model or serializer, you are referring to a particular field e.g. player in my case as you would when it is referenced as a foreign key.
In my case I had a Player model, and I wanted to update the reference in the save method of a Market model, when a weight is changed in the market, it should reflect immediately on the player.
class Market(models.Model):
player = models.ForeignKey(Player)
weight = models.CharField('Weight')
...
def save(self):
if self.weight:
# wrong
Player.objects.get(player=self.player) # this object reference of itself does not exist, hence the error
# right
Player.objects.get(pk=self.player.pk)
...
super().save()

Categories

Resources