Why doesnt it save the changes to fields - python

I'm trying to change the field values of my objects in my database.
I'm using the following commands
I dont know why it isn't saving the changes from false to true.
Please help.
is_approved and is_superuser are attributs of User u.
Thanks
EDIT:
Code for User model
class User(AbstractUser):
TRAINEE = 1
MENTOR = 2
MODERATOR = 3
SUBMENTOR = 4
USER_TYPES = (
(TRAINEE, 'Trainee'),
(MENTOR, 'Industry Expert'),
(MODERATOR, 'Moderator'),
(SUBMENTOR,'SubMentor')
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPES, null=True, blank=True)
is_approved = models.BooleanField(default=False)
has_paid_subscription = models.BooleanField(default=False)
date_of_birth = models.DateField(null=True, blank=True)
bio = models.CharField(max_length=2000, validators=[MinLengthValidator(100)], blank=True, null=True)
profile_picture = models.ImageField(upload_to=profile_media_path, default='default_profile_pic.jpg', blank=True, null=True)
profile_tags = models.ManyToManyField(Tag, blank=True, related_name='profiles')
signup_completed = models.BooleanField(default=False)
referral_code = models.CharField(max_length=100,null=True,blank=True)
def __str__(self):
return self.username
def save(self, *args, **kwargs):
super(User, self).save(*args, **kwargs)
if self.bio:
self.profile_tags.clear()
lda_model = lda.LDA([self.bio])
tags = lda_model.generate_tags()
for tag in tags:
name = str(tag).capitalize()
try:
tag_object = Tag.objects.get(tag_name=name)
except Tag.DoesNotExist:
tag_object = Tag(tag_name=name)
tag_object.save()
self.profile_tags.add(tag_object)
tag_object.save()
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
EDIT 2: Tried u[0].refresh_from_db() it didnt work

Declare the model you are editing.
user = u[0]
user.is_superuser=True
user.save()
There is something funky going on with accessing the user from the queryset that is preventing it from saving. Not clear on the details of why but you can get around it by following the above pattern.

Related

Is there a way to customize the value of specific field in a model in django when adding a new data?

I have a model here which I want to specify the value of unique_code everytime I'm adding a new data .
model.py
class Customer(models.Model):
LastName = models.CharField(max_length=45, blank=True)
FirstName = models.CharField(max_length=45, blank=True)
MiddleName = models.CharField(max_length=45, blank=True)
ExtensionName = models.CharField(max_length=45, blank=True)
GenderID = models.ForeignKey(Gender, on_delete=models.CASCADE)
id_pic = models.ImageField(null=True, blank=True, upload_to=upload_path)
otp = models.CharField(max_length=6, blank=True)
unique_code = models.CharField(max_length=8, blank=True)
verified = models.BooleanField(default=False)
already_claimed = models.BooleanField(default=False)
email = models.CharField(max_length=45, blank=True)
Birthdate = models.CharField(max_length=45, blank=True, null=True)
cellphone_number = models.CharField(max_length=45, blank=True, null=True)
agreement1 = models.BooleanField(null=True)
agreement2 = models.BooleanField(null=True)
agreement3 = models.BooleanField(null=True)
I try to override the save method to do that and here is my code
def save(self, *args, **kwargs):
self.unique_code = uuid.uuid4().hex[:8].upper()
super().save(*args, **kwargs)
but the problem with this approach is that the unique_code change everytime I update the data. and I want the unique_code to not change once the data has been save to database.
so is it possible to specify its value here in view.py
data = request.data
serializer = CustomerSerializer(data=data)
how to add unique_code = uuid.uuid4().hex[:8].upper() in this serializer = CustomerSerializer(data=data)
You can simply test to see if it exists already in your save() function, and only call it if it's not there. Then it will behave consistently across all attempts to save it.
def save(self, *args, **kwargs):
if not self.unique_code:
#object has no unique_code
self.unique_code = uuid.uuid4().hex[:8].upper()
super().save(*args, **kwargs)
Another approach is to always assign it on the first save, before the object has been assigned an ID. That way you know that any object that has been saved to the database will also have a unique_code
def save(self, *args, **kwargs):
if not self.id:
#object has no id
self.unique_code = uuid.uuid4().hex[:8].upper()
super().save(*args, **kwargs)

FieldError django

Please I need help, I dont know where the problem is coming from, please see the code below
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def post_feed_view(request, *args, **kwargs):
user = request.user
profiles = user.follow_user.all()
followed_users_id = []
if profiles.exists():
followed_users_id = [x.user.id for x in profiles]
followed_users_id.append(user.id)
queryset = Post.objects.filter(user__id__in=followed_users_id).order_by("-date_posted")
serializer = PostSerializer(queryset, many=True)
return Response(serializer.data, status=200)
I keep getting this error: Cannot resolve keyword 'user' into field. Choices are: author, author_id,
although, in my models, I dont have "User" what I have is "Author".
But I dont know where exactly to put in author. I think my problem is that i dont fully understand "request.user".
Please help!.
===========
This is the Profile and Follow models:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.CharField(max_length=245, null=True)
image = models.ImageField(default='default.png', upload_to='profile_pics')
interests = models.ManyToManyField(Category, related_name='interests_user')
stripe_customer_id = models.CharField(max_length=50, blank=True, null=True)
one_click_purchasing = models.BooleanField(default=False)
is_vendor = models.BooleanField(default=False)
# vendor
bvn = models.CharField(max_length=10, null=True, blank=True)
description = models.TextField(null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
company = models.CharField(max_length=100, null=True, blank=True)
# follow_user = models.ManyToManyField('users.Follow')
def __str__(self):
return f'{self.user.username} Profile'
#property
def followers(self):
return Follow.objects.filter(follow_user=self.user).count()
#property
def following(self):
return Follow.objects.filter(user=self.user).count()
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super().save()
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
class Follow(models.Model):
user = models.ForeignKey(User, related_name='user', on_delete=models.CASCADE)
follow_user = models.ForeignKey(User, related_name='follow_user', on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
old_instance = models.ForeignKey('Follow', blank=True, null=True, on_delete=models.CASCADE, editable=False)
def save(self, *args, **kwargs):
if self.pk is not None:
self.old_instance = Follow.objects.get(pk=self.pk)
super().save(*args,**kwargs)
def __str__(self):
return f"For: {self.user} // id: {self.id}"
class FollowerRelation(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey("Profile", on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
Your Post model apparently has no user field, but an author field, so you can filter with:
queryset = Post.objects.filter(
author_id__in=followed_users_id
).order_by('-date_posted')
But that being said, you should not filter like that. Given your models you can do this in a single query and thus avoiding the N+1 problem. You can simply filter with:
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def post_feed_view(request, *args, **kwargs):
queryset = Post.objects.filter(
author__follow_user__user=request.user
).order_by('-date_posted')
serializer = PostSerializer(queryset, many=True)
return Response(serializer.data, status=200)

Django Admin model create new instance instead of update

I've multiple models in my Django project but only this given below model creating another instance on update instead of save. This is happening in Django's Admin panel, not on my custom UI. When I remove my save() method then it works fine but this way I won't be able to create slug.
Does anybody know what I'm doing wrong in here
class Course(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='category')
slug = models.SlugField(max_length=200, unique=True, primary_key=True, auto_created=False)
short_description = models.TextField(blank=False, max_length=60)
description = models.TextField(blank=False)
outcome = models.CharField(max_length=200)
requirements = models.CharField(max_length=200)
language = models.CharField(max_length=200)
price = models.FloatField(validators=[MinValueValidator(9.99)])
level = models.CharField(max_length=20)
application_link = models.URLField(max_length=1000, blank=True, null=True)
brochure = models.FileField(upload_to='brochures/', blank=True, null=True)
thumbnail = models.ImageField(upload_to='thumbnails/')
video_url = models.CharField(max_length=100)
is_session_available = models.BooleanField(default=False)
session_url = models.CharField(max_length=250, default='')
is_published = models.BooleanField(default=True)
created_at = models.DateTimeField(default=now)
updated_at = models.DateTimeField(default=now)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Course, self).save(*args, **kwargs)
instead of overriding save method you could do this:
admin.py
class CourseAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)}
admin.site.register(Course, CourseAdmin)
It is happening because it will generate new slug every time. You can do something like this:
def generate_slug(self):
self.slug = slugify(self.name)
def save(self, *args, **kwargs):
if not self.slug:
self.generate_slug() # This will generate slug.
return super().save(*args, **kwargs)

How to filter the additional model in DetailView?

class Source(models.Model):
Name = models.CharField(max_length=150)`enter code here`
Address = models.CharField(max_length=150)
Office_Phone = PhoneField(blank=True, help_text='Office phone number')
Main_Contact = models.CharField(max_length=150, blank=True, null=True)
Contact_Email = models.EmailField(max_length=254, blank=True, null=True)
Contact_Phone = PhoneField(blank=True, help_text='Main Contact phone number')
Billing_Contact = models.CharField(max_length=150, blank=True, null=True)
Billing_Email = models.EmailField(max_length=254, blank=True, null=True)
Billing_Phone = PhoneField(blank=True, help_text='Billing Contact phone number')
Notes = models.CharField(max_length=250, blank=True, null=True)
def __str__(self):
return self.Name
def get_absolute_url(self):
return reverse('sources-detail', kwargs={'pk': self.pk})
class Rate(models.Model):
Source = models.ForeignKey(Source, on_delete=models.CASCADE)
Report_Type = models.ForeignKey(ReportType, on_delete=models.CASCADE)
Amount = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
class SourceDetailView(DetailView):
model = Source
template_name = 'intake/source_detail.html'
context_object_name = 'source'
def get_context_data(self, *args, **kwargs):
context = super(SourceDetailView, self).get_context_data(*args, **kwargs)
context['rates'] = Rate.objects.all.filter(***not sure what to put here***)
return context
Would it be better to filter it in the Template or do it in the View? I am able to get results if I don't filter it and just use Rate.objects.all(), and then I filter it in my template. Just think there is a better way to do this.
You can just fetch the relation in reverse:
class SourceDetailView(DetailView):
model = Source
template_name = 'intake/source_detail.html'
context_object_name = 'source'
def get_context_data(self, *args, **kwargs):
context = super(SourceDetailView, self).get_context_data(*args, **kwargs)
context['rates'] = self.object.rate_set.all()
return context
That being said, here it does not make much difference to make the query in the template, since there is only one object here, so there is no N+1 problem.

filter choices for many to many field in modelform django

i want to filter the many to many field in modelform.
class IdealBehaviour(models.Model):
cbs_role = models.ManyToManyField(CbsRole, null=True, blank=True)
cbs = models.ForeignKey('cbs.CBS', null=True, blank=True)
ideal_behaviour = models.CharField(max_length=500, null=True, blank=True)
Description = models.CharField(max_length=1000, null=True, blank=True)
created_time = models.DateTimeField(auto_now_add = True,null=True, blank=True)
class StandardWork(models.Model):
cbs_and_role = models.ManyToManyField('userdata.CbsRole', null=True, blank=True)
standard_work_number = models.BigIntegerField(null=True, blank=True)
system_name= models.CharField(max_length=500, null=True, blank=True)
system_description=models.TextField(null=True, blank=True)
ideal_behaviour = models.ManyToManyField ('userdata.IdealBehaviour', null=True, blank=True)
publish = models.BooleanField(default=False)
created_time = models.DateTimeField(auto_now_add = True,null=True, blank=True)
class TodoListForm(ModelForm): # used in manage view
class Meta:
model = StandardWork
exclude = ('publish', 'cbs_and_role', 'standard_work_number')
widgets = {
'system_description': forms.Textarea(attrs={'rows':3}),
}
i want to display the choices of ideal_behaviour for the query
cbsobject = CBS.objects.get(id=dat)
idealbehaviour = IdealBehaviour.objects.filter(cbs=cbsobject)
I want to choices for ideal_behaviour in TodoListForm as idealbehaviour only.
How can i query to display ideal-behaviour assosciated with that perticuler cbs only in modelform?
i got the solution
def __init__(self, *args, **kwargs):
super(PollForm, self).__init__(*args, **kwargs)
if self.instance:
print "printing in form"
print self.instance.id
self.fields['ideal_behaviour'].queryset = IdealBehaviour.objects.filter(cbs__exact=self.instance.id)
but i dont how to get the id for cbs. self.instance.id its giving for standardwork id. i want id for cbs. i.e cbsobject i want in form as a instance. after that its working fine.
Got the solution.
I don't know if it is feasible or not, but I put the forms in the views file only so I can get the instance for "cbsobject".
class PollForm(forms.ModelForm): # used in manage view
class Meta:
model = StandardWork
exclude = ('cbs_and_role','publish', 'standard_work_number')
widgets = {
'system_description': forms.Textarea(attrs={'rows':3}),
}
def __init__(self, *args, **kwargs):
super(PollForm, self).__init__(*args, **kwargs)
if self.instance:
print "printing in form"
print self.instance.id
self.fields['ideal_behaviour'].queryset = IdealBehaviour.objects.filter(cbs__exact=cbsobject)

Categories

Resources