I have two models, Account model & Thread model:
class Account(AbstractBaseUser, PermissionsMixin):
class Meta:
verbose_name_plural = "Account List"
email = models.EmailField(max_length=255, unique=True)
username = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, default="")
profile_image = models.ImageField(max_length=255, upload_to=profile_image_path, blank=True, null=True, unique=True)
about = models.TextField(max_length=255, default='Write something about yourself...', blank=True)
start_date = models.DateTimeField(default=timezone.now)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "name"]
def __str__(self):
return self.username
class Thread(models.Model):
options = (('active', 'Active'), ('deactivated', 'Deactivated'))
username = models.ForeignKey(Account, on_delete=models.CASCADE, to_field='username')
alt = models.TextField(max_length=255, blank=True)
image = models.ImageField(max_length=255, upload_to=thread_image_path, blank=True)
content = models.TextField(blank=True)
created = models.DateTimeField(blank=True, null=True, default=timezone.now)
status = models.CharField(max_length=11, choices=options, default='active')
If I have already created a thread that is ForeignKey to the Account model, I am not able to change the username of the Account model, returning the error FOREIGN KEY constraint failed. I guess the existing Thread model require a username to point to. Is there way to create a custom update method in view.py to update the ForeignKey automatically?
Here is my view.py:
class UserViewSet(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = Account.objects.all()
permission_classes = (AllowAny,)
EDIT:
serializer.py
class ThreadSerializer(serializers.ModelSerializer):
profile_image = serializers.SerializerMethodField('get_profile_image')
created = serializers.DateTimeField(format="%d %B, %Y %H:%M:%S")
class Meta:
model = Thread
fields = (
'id',
'username',
'profile_image',
'alt',
'image',
'content',
'created',
'status')
def get_profile_image(self, thread):
profile_image_url = thread.username.profile_image.url
return profile_image_url
Error:
IntegrityError at /account/auth/user/1/
FOREIGN KEY constraint failed
Request Method: PUT
Request URL: http://127.0.0.1:8000/account/auth/user/1/
Django Version: 4.0.4
Exception Type: IntegrityError
Exception Value:
FOREIGN KEY constraint failed
Exception Location: c:\Users\85291\Desktop\vscode\my-app\web\env\lib\site-packages\django\db\backends\sqlite3\base.py, line 477, in execute
Python Executable: c:\Users\85291\Desktop\vscode\my-app\web\env\Scripts\python.exe
Python Version: 3.10.2
Python Path:
['C:\\Users\\85291\\Desktop\\vscode\\my-app\\web\\jtravel',
'c:\\Users\\85291\\.vscode\\extensions\\ms-python.python-2022.6.3\\pythonFiles\\lib\\python\\debugpy\\_vendored\\pydevd',
'C:\\Python310\\python310.zip',
'C:\\Python310\\DLLs',
'C:\\Python310\\lib',
'C:\\Python310',
'c:\\Users\\85291\\Desktop\\vscode\\my-app\\web\\env',
'c:\\Users\\85291\\Desktop\\vscode\\my-app\\web\\env\\lib\\site-packages']
Server time: Sun, 05 Jun 2022 16:40:53 +0800
delete to_field='username'
username = models.ForeignKey(Account, on_delete=models.CASCADE)
it is a reason of an error
Related
Here i have two models Keys and Users i am creating POST API so i got encounter with this Error .
UserModel.py:
class Users(AbstractBaseUser):
vendor_name = models.ForeignKey(Vendor, on_delete=models.CASCADE, default=None)
key_value = models.ForeignKey(KeyTable, on_delete=models.CASCADE, default=None, null=True)
username = models.CharField(max_length=100, verbose_name="username", unique=True)
password = models.CharField(max_length=100)
hardware_id = models.CharField(max_length=150, null=True)
created_by = models.DateField(verbose_name="created_by", auto_now_add=True)
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ['password', 'hardware_id']
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_role_vendor = models.BooleanField(default=False)
is_role_customer = models.BooleanField(default=True)
def __str__(self):
return self.username
objects = UserManager()
KeyModel.py:
class KeyTable(models.Model):
key_id = models.IntegerField(unique=True, auto_created=True)
key_value = models.CharField(max_length=100)
issue_date = models.DateField(max_length=100)
expiry_date = models.DateField()
status = models.CharField(max_length=50)
license_tenure = models.IntegerField()
def __str__(self):
return self.key_value
KeySerializer:
class KeySerializer(serializers.ModelSerializer):
class Meta:
model: Keys
fields = ['key_id', 'key_value', 'issue_date', 'expiry_date', 'status', 'license_tenure']
Error Encounters:
django.db.utils.IntegrityError: NOT NULL constraint failed: app_users.key_value_id
you can set null=True and blank=True in the model field which is causing you an error
or you can delete the app and create it again with the same code this trick can also work.
But if you do not find solution then you can find several solutions here.
In DRF I am facing an issue, whenever I do a POST request on the endpoint, on the field "name" which is a text field I get an exception "Field 'id' expected a number but got 'TITLE'", but when I change the value of "name" to an integer the request is successful I don't understand it becauses name is TextField in model and why its mixing Id and Name field with each other. I have deleted the migration files from the Project and DB and re-run the Migrations, but still facing this issue.
Following is my code:
models.py
class Project(models.Model):
admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name='project_crated_by')
name = models.TextField(max_length=225, blank=False, null=False)
project_members = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='members', null=True, blank=True)
created_on = models.DateField(default=timezone.now)
tags = ArrayField(models.CharField(max_length=225, default=''), blank=True)
def __str__(self):
return self.name
objects = models.Manager()
views.py
class ProjectView(viewsets.ViewSet):
def create(self, request):
project_name_exist = Project.verify_project_name(request.data['admin'], request.data['name'])
if project_name_exist:
return Response({'message': 'You already have a project with this name',
'status': status.HTTP_200_OK})
serialized_project = ProjectSerializer(data=request.data)
if serialized_project.is_valid():
serialized_project.save()
return Response({'message': 'Project Created Successfully', 'status': status.HTTP_201_CREATED})
else:
return Response({'error': serialized_project.errors, 'status': status.HTTP_400_BAD_REQUEST})
serializer.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
A more generic and non-DIY solution is to use UniqueTogetherValidator on your serializer and let Django sort it out.
from rest_framework.validators import UniqueTogetherValidator
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
validators = [
UniqueTogetherValidator(
queryset=Project.objects.all(),
fields=['admin', 'name'],
message='You already have a project with this name'
)
]
And/or add it to the model for enforcing it on the database.
class Project(models.Model):
admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name='project_crated_by')
name = models.TextField(max_length=225, blank=False, null=False)
project_members = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='members', null=True, blank=True)
created_on = models.DateField(default=timezone.now)
tags = ArrayField(models.CharField(max_length=225, default=''), blank=True)
def __str__(self):
return self.name
objects = models.Manager()
class Meta:
unique_together = ("admin", "name")
I need to update the requested user field when I create the organization from OrganizationViewSet as below,
class OrganizationViewSet(viewsets.ModelViewSet):
queryset = Organization.objects.all()
serializer_class = OrganizationSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(admin_user=self.request.user)
data = serializer.data
org_id = data['id']
self.request.user.update(organization=org_id) # Error is coming from this line
The above code generates the following error,
'User' object has no attribute 'update'
Here is my User models.py file
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
organization = models.ForeignKey(
"organization.Organization", on_delete=models.CASCADE, null=True, blank=True)
first_name = models.CharField(max_length=200, blank=True)
last_name = models.CharField(max_length=200, blank=True)
phone = models.CharField(max_length=20, blank=True)
So my question is, how can I update the requested user organization? Any help?
update is a method on the QuerySet and not on a Model
You can do model.save as follows to have the desired behavior
self.request.user.organization_id = org_id
self.request.user.save()
I would like to get all posts of all users which my user follow.
My User model looks like
from django.db import models
from django.contrib.auth.models import AbstractUser
from apps.friend_request.models import FriendRequest
# Save avatar to user specific directory in media files
def user_avatar_directory(instance, filename):
return f'{instance.username}/avatar/{filename}'
class User(AbstractUser):
# Field that is used as the unique identifier
USERNAME_FIELD = 'email'
# Fields that are required when using createsuperuser (username_field and password fields are required by default)
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
# Fields that shall be treated as public and can be exposed to all logged-in users
PUBLIC_FIELDS = ('id', 'username', 'first_name', 'last_name', 'country')
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
country = models.CharField(max_length=150, blank=True, null=True)
city = models.CharField(max_length=150, blank=True, null=True)
about = models.TextField(blank=True, null=True)
avatar = models.ImageField(upload_to=user_avatar_directory, blank=True, null=True)
followers = models.ManyToManyField(to='self', symmetrical=False, related_name='followees', blank=True)
my post model
from django.db import models
from django.conf import settings
class Post(models.Model):
user = models.ForeignKey(
#to=User,
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='posts',
#null=True
)
content = models.CharField(
max_length=150,
blank=False
)
created = models.DateTimeField(
auto_now=True
)
liked_by = models.ManyToManyField(
#to=User,
to=settings.AUTH_USER_MODEL,
related_name='liked_posts',
blank=True
)
# TODO
# comments = Set('Comment')
# TODO sharing not yet clear what it is about
# shared = Optional('Post', reverse='sharing')
# sharing = Set('Post', reverse='shared')
def __str__(self):
return f'ID: {self.pk}: {self.content} '
class Post_Pic(models.Model):
created = models.DateTimeField(
auto_now=True
)
post_id = models.ForeignKey(
to=Post,
on_delete=models.CASCADE,
related_name='posts',
)
image = models.ImageField(
upload_to='post_pic'
)
def __str__(self):
return f'ID: {self.pk} Post: {self.post_id} File: {self.image.name}'
my views.py
class MyFollowersPosts(ListView):
"""
Get all followers
"""
queryset = Post.objects.all()
serializer_class = FollowesSerilizer
def get_queryset(self):
posts = []
for user in self.request.user.followers.all():
for post in Post.objects.filter(author=user.followed):
posts.append(post)
return posts
Problem is that I am always getting this error and I can´t find out where is problem
AttributeError at /backend/api/social/posts/following/
'AnonymousUser' object has no attribute 'followers'
Request Method: GET
Request URL: http://127.0.0.1:8000/backend/api/social/posts/following/
Django Version: 3.1.4
Exception Type: AttributeError
Exception Value:
'AnonymousUser' object has no attribute 'followers'
Exception Location: C:\Users\Dell\anaconda3\envs\motion-backend\lib\site-packages\django\utils\functional.py, line 241, in inner
Python Executable: C:\Users\Dell\anaconda3\envs\motion-backend\python.exe
Python Version: 3.9.1
Python Path:
['C:\Users\Dell\Desktop\day-5-django-motion-assignment',
'C:\Users\Dell\anaconda3\envs\motion-backend\python39.zip',
'C:\Users\Dell\anaconda3\envs\motion-backend\DLLs',
'C:\Users\Dell\anaconda3\envs\motion-backend\lib',
'C:\Users\Dell\anaconda3\envs\motion-backend',
'C:\Users\Dell\anaconda3\envs\motion-backend\lib\site-packages']
Server time: Mon, 04 Jan 2021 13:53:46 +0000
Your get_queryset should return a QuerySet, not a list. You furthermore do not need to obtain items with a loop, you can query with:
from rest_framework.permissions import IsAuthenticated
class MyFollowersPosts(ListView):
# …
permission_classes = [IsAuthenticated]
def get_queryset(self):
return Post.objects.filter(author__followees=self.request.user)
Furthermore the user should be logged in. You do this with the IsAuthenticated permission class.
You can use something like this :
user = request.user
followings_posts = Post.objects.filter(user__in = user.followees.all())
I have the following User,
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, max_length=255)
username = models.CharField(null=False, unique=True, max_length=255)
full_name = models.CharField(max_length=255, blank=True, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
And the following UserProfile model,
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, )
level = models.CharField(default="Noob", max_length=255)
reputation = models.IntegerField(default=0)
status = models.CharField(max_length=255, null=True, blank=True)
The User has a one to one relationship with Profile.
This is the UserSerializer,
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
location = LocationSerializer(read_only=True)
profile = UserProfileSerializer(read_only=True)
class Meta:
model = models.User
fields = (
'id', 'email', 'mobile', 'username', 'full_name', 'password', 'is_active', 'profile',
)
And this is the profile serializer.
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserProfile
fields = ('level', 'reputation', 'status',)
The issue is that in the serialized output for the user there is no nested profile data. How do I fix this. Any help appreciated.
all you need is set source for profile:
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
location = LocationSerializer(read_only=True)
profile = UserProfileSerializer(source='userprofile', read_only=True)
the userprofile is name of relation of your model User by onetoone to the UserProfle, other way you can set related_name for attribute user in the
UserProfle.
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
then your serializer will work fine as is.