Make django foreignkey varied - django

I want to make message model which handle 2 users.
class User(AbstractUser):
is_confirmed = models.BooleanField(default=False, choices=((True, 'True'), (False, 'False')), blank=True)
verification = models.CharField(max_length=100, null=True, default=None, blank=True)
pass_key = models.CharField(max_length=100, null=True, default=None, blank=True)
language = models.IntegerField(default=0)
def __str__(self):
return self.username
class Admin(User):
extra = models.CharField(max_length=50, null=True, default="")
...
class Client(User):
extra2 = models.CharField(max_length=50, null=True, default="")
...
class ChatMessage(models.Model):
sender = models.ForeignKey(Admin, related_name = 'sender_user', on_delete=models.CASCADE)
receiver = models.ForeignKey(Client, related_name = 'receiver_user', on_delete=models.CASCADE)
message = models.CharField(max_length = 200)
received_at = models.DateTimeField(auto_now_add = True)
session = models.ForeignKey(Session, on_delete=models.CASCADE)
is_read = models.BooleanField()
how can I make the sender and receiver in a way that can be admin or client.

Related

Sum in Django Rest Framework (DRF) Serializer

Excuse me devs, i wanna ask about how to count on drf serializer, i need codes that can serialized fields plant from table A and it relations with another table B with count of them "plants_active"
Here's my code:
# Models
class TablePlants(models.Model):
plant_id = models.CharField(primary_key=True, max_length=20, unique=True)
gateway = models.ForeignKey(
TableGatewayDevice, models.DO_NOTHING, blank=True, null=True)
name = models.CharField(max_length=150, blank=True, null=True)
date = models.DateField(blank=True, null=True)
contact_person = models.CharField(max_length=70, blank=True, null=True)
contact_email = models.CharField(max_length=50, blank=True, null=True)
contact_phone = models.CharField(max_length=30, blank=True, null=True)
plant_status = models.CharField(max_length=20, blank=True, null=True)
weather_status_code = models.ForeignKey(
TableAuxWeather, models.DO_NOTHING, db_column='weather_status_code', blank=True, null=True)
timezone = models.CharField(max_length=200, blank=True, null=True)
image = models.FileField(
upload_to='plants/', validators=[file_size, validate_file_extension], null=True, blank=True)
class Meta:
db_table = 'table_plants'
def __str__(self):
return 'TablePlants[id: {id}, name: {name}]'.format(
id=self.id, name=self.name)
class PVOwner(models.Model):
pv_owner_id = models.AutoField(primary_key=True)
company = models.ForeignKey(TableCompany, on_delete=CASCADE,
blank=True, null=True, related_name="pv_owner_company")
class Meta:
db_table = 'table_pv_owner'
class TableSitePlant(models.Model):
pv_owner = models.ForeignKey(
PVOwner, on_delete=CASCADE, blank=True, null=True, related_name="pv_site_owner_plant")
site_owner = models.ForeignKey(
SiteOwner, on_delete=CASCADE, blank=True, null=True, related_name="site_owner_plant")
plant = models.ForeignKey(TablePlants, on_delete=CASCADE,
blank=True, null=True, related_name="site_plant")
class Meta:
db_table = 'table_site_plant'
# Serializer
class MainMenuSerializer(serializers.ModelSerializer):
plants_active = serializers.IntegerField(source="plant")
class Meta:
model = TableSitePlant
fields = ['plants_active']
# Views
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter(plant__plant_status='offline')
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
What i expecting is i can count how many plants that have status online
You can use the get method to return response as you desired.
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter()
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
def get(self, request):
queryset = self.get_queryset().filter(plant__plant_status='online')
return Response({
"active_plants": queryset.count(),
})

get the related records in a serializer - django

I am trying to obtain in a query the data of a client and the contacts he has registered I tried to do it in the following way but it did not work.
class ClientReadOnlySerializer(serializers.ModelSerializer):
clientcontacts = ClientContactSerializer(many=True, read_only=True)
class Meta:
model = Client
fields = "__all__"
Is there any way to make this relationship nested?
these are my models
clients model
# Relations
from apps.misc.models import City, TypeIdentity, TypeCLient, CIIU
from apps.clients.api.models.broker.index import Broker
from apps.authentication.models import User
class Client(models.Model):
id = models.CharField(max_length=255, unique=True,primary_key=True, editable=False)
type_client = models.ForeignKey(TypeCLient, on_delete=models.CASCADE, blank=True)
type_identity = models.ForeignKey(TypeIdentity, on_delete=models.CASCADE, blank=True)
document_number = models.CharField(max_length=255, blank=True, unique=True)
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
social_reason = models.CharField(max_length=255, blank=True, null=True)
city = models.ForeignKey(City, on_delete=models.CASCADE, blank=True)
address = models.CharField(max_length=255, blank=True)
email = models.CharField(max_length=255, blank=True, unique=True)
phone_number = models.CharField(max_length=255, blank=True, unique=True)
ciiu = models.ForeignKey(CIIU, on_delete=models.CASCADE, blank=True)
broker = models.ForeignKey(Broker, on_delete=models.CASCADE, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
income = models.SmallIntegerField(blank=True, default=0)
state = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True, default=None)
client contacts model
# Relations
from apps.clients.api.models.index import Client
class ClientContact(models.Model):
id = models.CharField(max_length=255, primary_key=True, unique=True, editable=False)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
phone_number = models.CharField(max_length=255)
state = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True, blank=True, default=None)
after some research I came up with a solution that doesn't seem very practical, what I did was to create a method in the serializer that queries the client's contacts as follows
class ClientReadOnlySerializer(serializers.ModelSerializer):
contacts = serializers.SerializerMethodField(method_name='get_contacts')
class Meta:
model = Client
fields = "__all__"
extra_fields = ['contacts']
def get_contacts(self, obj):
contacts = ClientContact.objects.filter(client=obj)
serializer = ClientContactSerializer(contacts, many=True)
return serializer.data
using the model and the serializer of the contact model I made a query which I added in an extra field of the customer serializer, if someone knows how to make this process more optimal please reply.

How to display one models data in another model django admin panel

I have two models: 1) SchoolProfile & 2) Content
I want to show content data in schoolprofile, But data should be display as per user foreignkey.
User foreignkey common for both the models.
School Profile Model
class SchoolProfile(models.Model):
id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE,unique=True)
school_name = models.CharField(max_length=255)
school_logo=models.FileField(upload_to='media/', blank=True)
incharge_name = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, blank=True)
phone_num = models.CharField(max_length=255, blank=True)
num_of_alu = models.CharField(max_length=255, blank=True)
num_of_student = models.CharField(max_length=255, blank=True)
num_of_cal_student = models.CharField(max_length=255, blank=True)
def __str__(self):
return self.school_name
Content Model
class Content(models.Model):
id=models.AutoField(primary_key=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
content_type = models.CharField(max_length=255, blank=True, null=True)
show=models.ForeignKey(Show,on_delete=models.CASCADE, blank=True, null=True)
sponsor_link=models.CharField(max_length=255, blank=True, null=True)
status=models.BooleanField(default=False, blank=True, null=True)
added_on=models.DateTimeField(auto_now_add=True)
content_file=models.FileField(upload_to='media/', blank=True, null=True)
title = models.CharField(max_length=255)
subtitle = models.CharField(max_length=255, blank=True, null=True)
description = models.CharField(max_length=500, blank=True, null=True)
draft = models.BooleanField(default=False)
publish_now = models.CharField(max_length=255, blank=True, null=True)
schedule_release = models.DateField(null=True, blank=True)
expiration = models.DateField(null=True, blank=True)
tag = models.ManyToManyField(Tag, null=True, blank=True)
topic = models.ManyToManyField(Topic, null=True, blank=True)
category = models.ManyToManyField(Categorie, null=True, blank=True)
def __str__(self):
return self.title
I have used Inline but it's show below error:
<class 'colorcast_app.admin.SchoolProfileInline'>: (admin.E202) 'colorcast_app.SchoolProfile' has no ForeignKey to 'colorcast_app.SchoolProfile'.
My admin.py
class SchoolProfileInline(InlineActionsMixin, admin.TabularInline):
model = SchoolProfile
inline_actions = []
def has_add_permission(self, request, obj=None):
return False
class SchoolProfileAdmin(InlineActionsModelAdminMixin,
admin.ModelAdmin):
inlines = [SchoolProfileInline]
list_display = ('school_name',)
admin.site.register(SchoolProfile, SchoolProfileAdmin)
Using the StackedInline to link two models is straight forward and a much clean practice, so basically this is my solution below:
class ContentInlineAdmin(admin.StackedInline):
model = Content
#admin.register(SchoolProfile)
class SchoolProfileAdmin(admin.ModelAdmin):
list_display = ('school_name',)
inlines = [ContentInlineAdmin]

django RelatedObjectDoesNotExist error while creating

models:
class FullNameMixin(models.Model):
name_id = models.BigAutoField(primary_key = True, unique=False, default=None, blank=True)
first_name = models.CharField(max_length=255, default=None, null=True)
last_name = models.CharField(max_length=255, default=None, null=True)
class Meta:
abstract = True
class Meta:
db_table = 'fullname'
class User(FullNameMixin):
id = models.BigAutoField(primary_key = True)
username = models.CharField(max_length=255, unique=True)
email = models.CharField(max_length=255, unique=True)
token = models.CharField(max_length=255, unique=True, null=True, blank=True)
password = models.CharField(max_length=255)
role = models.IntegerField(default=1)
verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
def __str__(self):
return self.username
class Meta:
db_table = 'cga_user'
class Profile(FullNameMixin):
id = models.BigAutoField(primary_key = True)
birthday = models.DateTimeField(null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
postcode = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=255, null=True, blank=True)
profession_headline = models.CharField(max_length=255, null=True, blank=True)
image = models.ImageField(upload_to=get_upload_path, null=True, blank=True)
profile_banner = models.ImageField(upload_to=get_upload_path_banner, null=True, blank=True)
cga_user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE, related_name="profile")
gender = models.CharField(
max_length=255, blank=True, default="", choices=USER_GENDER_CHOICES
)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
class Meta:
db_table = 'profile'
When i am creating Profile from django admin panel getting below error.
e
filename = self.upload_to(instance, filename)
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/api/model_utils/utils.py", line 7, in get_upload_path
instance.user,
File "/Users/soubhagyapradhan/Desktop/upwork/africa/backend/env/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 421, in __get__
raise self.RelatedObjectDoesNotExist(
api.models.FullNameMixin.user.RelatedObjectDoesNotExist: Profile has no user.
[24/Jul/2021 13:49:51] "POST /admin/api/profile/add/ HTTP/1.1" 500 199997
please take a look how can i fix this.
Note: User model creation working but, profile not working
I checked in drf and django admin panel .
both place not working.
The problem here is that you are declaring a User model which is in fact just a model. That's not how it works.
The User is a special type of model and if you want to change it you have to extend the AbstractUser class.
Alternatively you can connect to it via one-to-one classes in the classic user-profiles approach.
But here you are creating a user model that (besides using the reserved word 'User') has none of the requirements necessary to be treated as a user who can be authenticated and that can instantiate sessions.
> Example of a simple user-profiles architecture
> Working with User objects - Django Docs (i particularly recommend this one)
I would recommend you to read-up on django user authentication.

Build Inline Formsets in Django Admin

So I am new to Django and I have been reading a lot of documentation to figure this out, I have a table called "Logs" that has logs of different positions (has FK of table "Position"), each position belongs to a department (has FK to table "Department") Check the image below :1
What I want to do is create a view just like this one :
2
and whenever you click on a department, it extends all the positions in it with their respective logs like this :
3
The Screenshots I have attached are my work in main app (or if you would like to call it front end), I wanted to replicate the same process in the Django Admin page, I keep seeing that I should use inlines but I can't seem to make it work, can someone help or put me in the right direction please ? much appreciated.
Here is what I have in my models.py :
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Site(models.Model):
site = models.CharField(max_length=200, blank=True, null=True)
totalHC = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.site
class Department(models.Model):
department = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.department
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE, null=True, default=Site(id="1").site)
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=2000, blank=True)
skills = models.CharField(max_length=2000, blank=True)
aoi = models.CharField(max_length=2000, blank=True)
github = models.CharField(max_length=200, blank=True)
linkedin = models.CharField(max_length=200, blank=True)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
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 Grade(models.Model):
user = models.OneToOneField(Profile, on_delete=models.CASCADE)
ut1 = models.CharField(max_length=200, blank=True)
ut2 = models.CharField(max_length=200, blank=True)
ut3 = models.CharField(max_length=200, blank=True)
ut1p = models.ImageField(upload_to='plots', blank=True)
ut2p = models.ImageField(upload_to='plots', blank=True)
ut3p = models.ImageField(upload_to='plots', blank=True)
ut1pb = models.ImageField(upload_to='plots', blank=True)
ut2pb = models.ImageField(upload_to='plots', blank=True)
ut3pb = models.ImageField(upload_to='plots', blank=True)
ut12 = models.ImageField(upload_to='plots', blank=True)
ut13 = models.ImageField(upload_to='plots', blank=True)
ut23 = models.ImageField(upload_to='plots', blank=True)
class Section(models.Model):
class Meta:
verbose_name = 'Department'
verbose_name_plural = 'Departments'
section = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.section
class Question(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
section = models.ForeignKey(
"Section", on_delete=models.CASCADE, null=True, blank=True)
question_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return self.question_field
class Answer(models.Model):
class Meta:
verbose_name = 'Log'
verbose_name_plural = 'Logs'
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
answer_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return f"{self.user} answered {self.answer_field}"
class Position1(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True, blank=True)
position = models.CharField(max_length=200, blank=True)
jobID = models.CharField(max_length=200, blank=True)
class HCtype(models.TextChoices):
Staff = 'Staff', ('Staff')
IDL = 'IDL', ('IDL')
DL = 'DL', ('DL')
hctype = models.CharField(
max_length=5,
choices=HCtype.choices,
)
def __str__(self):
return self.position
class Log(models.Model):
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
INN = models.IntegerField(blank=True, null=True)
OUT = models.IntegerField(blank=True, null=True)
date = models.CharField(max_length=200, blank=True)
internal = models.IntegerField(default=0, null=True)
class SiteHasPosition(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
standard = models.IntegerField(blank=True, null=True)
turn_over = models.IntegerField(blank=True, null=True)
class SiteHasDepartment(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
class SiteKPIs(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
date = models.CharField(max_length=200, blank=True)
staff = models.IntegerField(blank=True, null=True)
dl = models.IntegerField(blank=True, null=True)
idl = models.IntegerField(blank=True, null=True)
total_hc = models.IntegerField(blank=True, null=True)
total_in = models.IntegerField(blank=True, null=True)
total_out = models.IntegerField(blank=True, null=True)
staff_rate = models.IntegerField(blank=True, null=True)
dl_rate = models.IntegerField(blank=True, null=True)
idl_rate = models.IntegerField(blank=True, null=True)
Here is how I registred them in admin.py :
admin.site.register(Profile)
admin.site.register(Log)
admin.site.register(Position1)
admin.site.register(Department)
admin.site.register(Site)
admin.site.register(SiteHasDepartment)
admin.site.register(SiteHasPosition)
I would like to have a page in admin.py where I can select a site and for that specific site display :
all the departments(when you press a dpt all the positions will expand) for each position the standardHC, attributes from the Log table (that match that position,and that site) and attributes from SiteHasPosition( that match the site and that position)
I hope I made it clearer