We use djangoql for easy search in our django admin panel.
The mixin DjangoQLSearchMixin has been added to some of our models in the admin panel.
And sometimes after deployment we get an error in the handler
application_name/model_name/introspect/
Error:
FieldDoesNotExist at /admin/user/user/introspect/
Model_name has no field named 'field_name'
After the reboot, the error disappears. The error cannot be reproduced locally.
Example:
"Address has no field named 'membership_requests'"
#admin.register(MembershipRequest, site=admin_site)
class MembershipRequestAdmin(DjangoQLSearchMixin, admin.ModelAdmin):
list_display = ("company", "user", "request_type", "status", "created_on", "updated_on")
class MembershipRequest(PureModelMixin):
company = models.ForeignKey("constrafor.Company", on_delete=models.CASCADE, related_name="membership_requests")
user = models.ForeignKey("user.User", on_delete=models.CASCADE, related_name="membership_requests")
address = models.OneToOneField(
"constrafor.Address",
related_name="membership_requests",
on_delete=models.CASCADE,
null=True,
blank=True,
help_text="FK to constrafor.Address",
)
code = models.ForeignKey(
"constrafor.Code", on_delete=models.SET_NULL, related_name="membership_requests", blank=True, null=True
)
company_name = models.CharField(null=True, blank=True, max_length=1000)
company_phone = models.CharField(null=True, blank=True, max_length=15)
company_type = models.CharField(max_length=15, choices=Company.COMPANY_TYPE_CHOICES)
is_needed_email_verification = models.BooleanField(default=False)
status = models.CharField(
max_length=8,
choices=MembershipRequestStatus.choices,
default=MembershipRequestStatus.pending,
)
request_type = models.CharField(
max_length=10,
choices=MembershipRequestType.choices,
default=MembershipRequestType.natural,
)
As I remarked in an earlier comment on your question, this seems to be a very tricky heisenbug. Not being able to properly debug it, as it cannot be reproduced, I found a way around it:
class CustomDjangoQLSchema(DjangoQLSchema):
def get_field_instance(self, model, field_name):
"""Some obscure heisenbug caused introspect requests to raise, rendering DjangoQL useless.`
This catch the exception and just skip the problematic field.
"""
try:
return super().get_field_instance(model, field_name)
except FieldDoesNotExist:
return None
If you use this Schema instead of the default you should be able to skip those failing fields.
UPDATE: Later I found out that the model that caused trouble was not registered with Django properly. It makes sense that a model that is not imported in models.__init__ but that does have a referral causes unexpected behaviour like this.
Related
I searched for this problem everywhere without being able to find an answer though it seems basic DRF usage, so I might be missing sth.
I have a Customer model with certain required fields:
from django.db import models
from django.utils.translation import gettext_lazy as _
from applications.core.models.country import Country
from applications.core.models.customer_states.customer_state import \
CustomerState
class Customer(models.Model):
class Meta:
verbose_name = _('customer')
verbose_name_plural = _('customers')
user_email = models.EmailField(_('email'), max_length=100, unique=True, default=None)
complete_name = models.CharField(_('complete name'), max_length=200, default=None)
phone = models.CharField(_('phone'), max_length=50, default=None)
country = models.ForeignKey(Country, models.PROTECT, verbose_name=_('country'), default=None)
city = models.CharField(_('city'), max_length=100, default=None)
city_state = models.CharField(_('city state'), max_length=100, default=None)
address = models.CharField(_('address'), max_length=100)
zip_code = models.CharField(_('zip code'), max_length=50, default=None)
customer_state = models.OneToOneField(CustomerState, models.PROTECT)
notes = models.TextField(_('notes'), max_length=200, blank=True, null=True)
And I have this serializer:
from rest_framework import serializers
from applications.core.models.customer import Customer
from applications.core.models.customer_states.implementations.pending_manual_validation_state import \
PendingManualValidationState
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
def to_internal_value(self, data):
self.add_default_state_if_missing(data)
return super(CustomerSerializer, self).to_internal_value(data)
#staticmethod
def add_default_state_if_missing(data):
data['customer_state'] = PendingManualValidationState.objects.create().pk
Though I have explicitly told DRF that it should use all model's fields it does not seem to check for the requirement of fields like 'address' and whenever I create the serializer with data missing 'address' and call serializer.is_valid() it returns True.
Why?
Found the answer by myself:
It would seem that default=None in the field makes DRF realize that even if the field is required, not receiving data for it is not a problem.
I set those default because otherwise Django would set a '' default value and thus, PostgreSQL would not raise exceptions for those empty data fields. But now that I am starting to use DRF for validations I no longer need those default.
Yet, if I happen to create and save a Customer without using the serializer, then I risk letting Django create a field with a default '' without having PostgreSQL complain about it. I figure that risk has a low probability though.
I have three models in my django app...a members model, an application model and an applications review model.
My members model looks like this...
class Members(models.Model):
TITLES = (
('chairman', 'Chairman'),
('secretary', 'Secretary')
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.CharField(max_length=10, choices=TITLES, default='secretary')
My Applications model...
class Application(models.Model):
firstname = models.CharField(max_length=20)
middlename = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
dob = DateField()
The applications review model...
class ApplicationsReview(models.Model):
APPLICATION_STATUS = (
('pending', 'Pending Review'),
('approved', 'Approved'),
('rejected', 'Rejected')
)
applicant = models.OneToOneField(Application, on_delete=models.CASCADE, primary_key=True)
chairman = models.ForeignKey(Members, related_name='chairs', on_delete=models.CASCADE)
secretary = models.ForeignKey(Members, related_name='secretaries', on_delete=models.CASCADE)
application_status = models.CharField(max_length=10, choices=APPLICATION_STATUS, default='pending')
status_justification = models.TextField()
date = models.DateTimeField(auto_now_add=True)
When an application is created, I would like its review instantiated as well, hence, I have the following signal right below the applications review model...
# When an application is created, create with it an application review and associate it with the application instance
#receiver(post_save, sender=Application)
def create_application_review(sender, **kwargs):
instance = kwargs['instance']
created = kwargs['created']
if created:
ApplicationReview.objects.create(applicant=instance)
However, when I try to add an application in django admin I get the error
null value in column "chairman_id" violates not-null constraint
DETAIL: Failing row contains (3, pending, 2019-02-08 03:26:04.643452+00, null, null).
The error seems to be as a result of the signal trying to instantiate an ApplicationsReview instance without providing the values for the chairman and secretary. Even setting those to allow null fields doesn't get rid of the error. Is there something I'm missing here?
Creating ApplicationsReview requires you to pass the following details - chairman, secretary, status_justification But while creating ApplicationReview in the signal you are just passing value of applicant, So Django is assuming the values of chairman, secretary, status_justification fields as Null that is why you are getting this error.
If you want to make these field Non-compulsory you can pass null=True, Blank=True while defining the field in the model.
Something like this:
chairman = models.ForeignKey(Members, null=True, blank=True, related_name='chairs', on_delete=models.CASCADE)
# End
You can refer this answer to get more understanding of when to use null=True, blank=True or both.
https://stackoverflow.com/a/8609425/6280433
I was trying to adjust a DateField in one of my models to also show the time (DateTimeField). I ended up also making timezone adjustments. After all I decided to not use the time and deleted the additional code and set the field back to DateField. Migrations are made and migrated. Now when trying to access an object from the model either via the page or admin page I receive the error:
invalid literal for int() with base 10: b'24 22:00:00'
So after trying a few things I just wanted to delete the objects in the model using the admin page. This also resulted in the above error.
It seems every page relying on an object from that model throws the error.
Is there a way to force delete objects?
Can you recommend any other clean up methods?
The model is defined as:
class PieceInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular Piece across whole system')
piece = models.ForeignKey('Piece', on_delete=models.SET_NULL, null=True)
version = models.CharField(max_length=200)
date_claimed = models.DateField(null=True, blank=True)
claimant = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
date_sent_to_claimant = models.DateField(null=True, blank=True)
PIECE_STATUS = (
('n', 'Not Claimable'),
('a', 'Available'),
('r', 'Reserved'),
('c', 'Claimed'),
)
status = models.CharField(
max_length=1,
choices=PIECE_STATUS,
blank=True,
default='a',
help_text='Piece Availability',
)
#property
def claimed_overdue(self):
days_till_claimed_overdue = 7
if self.date_claimed and date.today() > self.date_claimed + timedelta(days=days_till_claimed_overdue):
return True
return False
class Meta:
ordering = ['date_claimed']
permissions = (('can_mark_sent_to_claimant', 'Set Piece Instance as sent to claimant'),)
def __str__(self):
return f'{self.id} ({self.piece.title})'
Since my project is not big I decided to drop the whole database and set it up again from scratch.
I used the accepted answer of this question
Note that you also have to set up all users again (including the superuser)
A quick question about django import-export. Suppose I have a model like the one in the docs, but with some additional constraints (note the Meta class):
class Book(models.Model):
name = models.CharField('Book name', max_length=100)
author = models.ForeignKey(Author, blank=True, null=True)
author_email = models.EmailField('Author email', max_length=75, blank=True)
imported = models.BooleanField(default=False)
published = models.DateField('Published', blank=True, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
categories = models.ManyToManyField(Category, blank=True)
def __unicode__(self):
return self.name
class Meta:
unique_together = ('name', 'author')
On bulk upload, I would ideally like that any rows containing errors (duplicate entries in this case -- but could be other type of "corrupt" rows too) to be skipped and the rest of the upload to continue. The corrupt rows should be logged into a file containing the row(s) in question and an additional column with the exception name.
There is a generic exceptions.py file :
class ImportExportError(Exception):
"""A generic exception for all others to extend."""
pass
class FieldError(ImportExportError):
"""Raised when a field encounters an error."""
pass
But it is not clear how to deal with the row by row situation and skipping. Any help from anyone who's dealt with this would greatly appreciated.
documentation is pretty clear:
dry_run is a Boolean which determines if changes to the database are
made or if the import is only simulated. It defaults to False.
raise_errors is a Boolean. If True, import should raise errors. The
default is False, which means that eventual errors and traceback will
be saved in Result instance.
This is are my models i want to relate. i want for collection to appear in the form of occurrence.
class Collection(models.Model):
id = models.AutoField(primary_key=True, null=True)
code = models.CharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
collection_name = models.CharField(max_length=100)
def __unicode__(self):
return self.collection_name
class Meta:
db_table = u'collection'
ordering = ('collection_name',)
class Occurrence(models.Model):
id = models.AutoField(primary_key=True, null=True)
reference = models.IntegerField(null=True, blank=True, editable=False)
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
modified = models.DateTimeField(null=True, blank=True, auto_now=True)
class Meta:
db_table = u'occurrence'
Every time i go to check the Occurrence object i get this error
TemplateSyntaxError at /admin/hotiapp/occurrence/
Caught an exception while rendering: column occurrence.collection_id does not exist
LINE 1: ...LECT "occurrence"."id", "occurrence"."reference", "occurrenc..
And every time i try to add a new occurrence object i get this error
ProgrammingError at /admin/hotiapp/occurrence/add/
column occurrence.collection_id does not exist
LINE 1: SELECT (1) AS "a" FROM "occurrence" WHERE "occurrence"."coll...
What am i doing wrong? or how does ForeignKey works?
The problem is that you have not updated your database table definition since adding the ForeignKey. syncdb doesn't do this for you, as the documentation clearly states. You need to update the SQL manually, or use a tool like South.
Are you sure you mean
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
Nullable and Unique? This may not be possible in some databases.
Generally, the unique constraint doesn't seem to make much sense here.
Are you trying to force a 1-to-1 relationship? Use the OneToOneField. http://docs.djangoproject.com/en/1.1/ref/models/fields/#django.db.models.OneToOneField