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)
Related
I am trying to assign value to a database entry that is defined using the models.ForeignKey. How should I refer to the variables in the referred model?
In the code below, the assignment update_user.appointments.requester_name = requesting_user does not work. Googling has not helped me find the right solution. How should one refer to such variables from django/python?
Below is my models.py
class AppointmentRequest(models.Model):
my_name = models.TextField(default='')
requester_name = models.TextField(default='')
meeting_year = models.TextField(default='')
class CustomUser(AbstractUser):
firstname = models.TextField(default='')
lastname = models.TextField(default='')
appointments = models.ForeignKey(AppointmentRequest, on_delete=models.CASCADE, default='', blank=True, null=True)
I want to modify the value of appointments entry, i.e., my_name, requester_name, etc.
Below is the code in views.py
def book_appointment(request):
requesting_user = request.GET['requesting_user']
update_user = CustomUser.objects.get(username=requested_user)
update_user.appointments.requester_name = requesting_user
The reason you're probably getting the "NoneType" object has not attribute "requester_name" is that update_user.appointments is probably null
appointments = models.ForeignKey(AppointmentRequest, on_delete=models.CASCADE, default='', blank=True, null=True)
That says your ForeignKey can be null, so that's what it's probably returning to you.
What you should really do is:
if update_user.appointments:
update_user.appointments.requester_name = request.GET['requesting_user']
else:
apt_request = AppointmentRequest()
apt_request.requester_name = request.GET['requesting_user']
apt_request.save()
update_user.appointments = apt_request()
update_user.save()
This creates an AppointmentRequest object that you use to set the appointments ForeignKey IF update_user.appointments is null.
ALSO, in this code:
appointments = models.ForeignKey(AppointmentRequest, on_delete=models.CASCADE, default='', blank=True, null=True)
I'm pretty sure default='' does nothing and it defaults to null. So you can omit that part of the code.
Cont in comments...:
Oh. Another thing. I wouldn't use ForeignKeys for this. I would Use ManyToMany unless the user is only allowed ONE appointment ever.
requesting_user = request.GET['requesting_user']
in this part you are getting the user as json not a django model instance, so when you apply
update_user = CustomUser.objects.get(username=requested_user)
it doesn't get any thing.
you should use django serializer to make a userSerializer then use it to convert the json user to model instance then when you apply
update_user = CustomUser.objects.get(username=requested_user)
this should work.
I'm trying to figure it out on how I can show only a specific set of dynamic fields in eav to a unique registered model in my apps.models. But I don't know how to this, I've also read the documents but I can't seem to find anything about it, or maybe I've come across it and didn't understand.
Now, what is happening is that, when I add an attribute in the django admin. It also adds the dynamic field in all the models registered in the eav.
What I want to do is that;
model 1 - dynamic_field1, dynamic_field2, dynamic_field3
model 2 - dynamic_field4, dynamic_field5, dynamic_field6
Btw, I'm currently using the django-eav2 the documentation is in the link. I've found my solution for my initial use case here link
Below codes are basically on how to register my models to the eav. Here is my sample models
class ClientName(models.Model):
name = models.CharField(max_length=250, null=True, blank=True)
description = models.TextField(null=True, blank=True)
is_active = models.BooleanField(default=True)
def __str__(self):
return str(self.name)
class CallDetails(models.Model):
client_name = models.ForeignKey(ClientName, on_delete=models.PROTECT, null=True, blank=True, db_index=True)
letter_info = models.TextField(null=True, blank=True)
def __str__(self):
return str(self.client_name)
class Meta:
verbose_name = 'Call Detail'
ordering = ['client_name']
eav.register(ClientName)
eav.register(CallDetails)
below is my admin.py
class CallDetailsAdminForm(BaseDynamicEntityForm):
model = CallDetails
class CallDetailsAdmin(BaseEntityAdmin):
form = CallDetailsAdminForm
admin.site.register(CallDetails, CallDetailsAdmin)
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
models.py
Good night friends, I would like to know if there is a possibility that every time I register a new move, the django administrator checks what is a 'hydrographic region' and adds the value that is entering with the 'balance_box'.
class Movement(models.Model):
TYPE_MOVE = (
('1', 'Receita'),
('2', 'Despesa'),
)
regiao_hidrografica = models.ForeignKey(RegiaoHidrografica, verbose_name="Região Hidrografica", null=False)
origem = models.ForeignKey(Origem, verbose_name="Origem", null=False)
finalidade_recurso = models.ForeignKey(FinalidadeRecursos, verbose_name="Finalidade de Recursos", null=True)
descricao = models.TextField("Descrição", null=True)
valor = MoneyField(max_digits=10, decimal_places=2, default_currency='BRL')
data_refencia = MonthField("Data de Referencia", help_text="Informe mês e ano")
# data_refencia = models.DateField("Data de Referencia", null=True, blank=True, default=None)
tipo_movimento = models.CharField(max_length=1, default=1, choices=TYPE_MOVE)
def __str__(self):
return self.descricao
def update_total_valor(self):
total = 0
self.movimento_set:
total += mov.valor
self.saldo_caixa = total
self.save()
class RegiaoHidrografica(models.Model):
name = models.CharField("Nome", max_length=100, null=False)
sigla = models.CharField("Sigla", max_length=10, null=True)
taxa_inea = models.IntegerField(default=10, null=True)
taxa_trans = models.IntegerField(default=0, null=True)
saldo_caixa = MoneyField('Saldo em caixa estimado', max_digits=10, decimal_places=2, null=True, default=0, default_currency='BRL')
saldo_cc = MoneyField('Saldo em conta estimado', max_digits=10, decimal_places=2, null=True, default=0, default_currency='BRL')
def __str__(self):
return self.name
I tried something like this, create this method in the 'class MovimentoAdmin(admin.ModelAdmin)', but it did not work.
admin.py
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
instance.save()
formset.save_m2m()
instance.RegiaoHidrografica.update_total_valor()
Would anyone have a hint how I could do this?
Sounds to me like you need Django Signals.
You can register a listener on the post_save signal for your model Movement. The listener then would check for changes (it can also detect object creation with the parameter created) and react accordingly.
However, this would not only apply to Django Administrator but rather to all positions in your code where a Movement object got created. If you only create those objects via the admin site you are fine.
Otherwise, consider overwriting the Django ModelAdmin.save_model method:
Example in Django documentation. This method also provides you with the ability to detect object creation as well.
If you really want to use the save_formset method instead, check your code. update_total_valor is defined in and for class Movement and not RegiaoHidrografica according to your snippet, the method in admin.py is defined on Movement (which is fine, but then your access to RegiaoHidrografica looks wrong to me, since you are trying to access a class name instead of the model property).
I recommend to work with Django signals here, they provide a ton of comfort (but also have a trade-off: Added processing time when saving an object...
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.