django - model for a messaging app between users - django

How do I go about creating a message app, between users. What's the business logic for creating the model? All I can think of was like this:
models.py
class Message(models.Model):
description = models.TextField()
date_added = models.DateTimeField(default=datetime.now)
sender = models.ForeignKey(User)
recipient = models.ForeignKey(User)
I am not very sure if this is the way to go. If you could kindly guide me on how to get started, will be very thank full. Thank you!

My variant for common cases:
from django.utils.translation import ugettext_lazy as _
class Message(models.Model):
"""
A private message from user to user
"""
subject = models.CharField(_("Subject"), max_length=120, blank=True)
body = models.TextField(_("Body"))
sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='sender_messages', verbose_name=_("Sender"), )
recipient = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='receiver_messages', null=True, blank=True, verbose_name=_("Recipient"))
parent_msg = models.ForeignKey('self', related_name='next_messages', null=True, blank=True, verbose_name=_("Parent message"))
sent_at = models.DateTimeField(_("sent at"), null=True, blank=True)
read_at = models.DateTimeField(_("read at"), null=True, blank=True)
replied_at = models.DateTimeField(_("replied at"), null=True, blank=True)
sender_deleted_at = models.DateTimeField(_("Sender deleted at"), null=True, blank=True)
recipient_deleted_at = models.DateTimeField(_("Recipient deleted at"), null=True, blank=True)
ip = models.GenericIPAddressField(verbose_name=_('IP'), null=True, blank=True)
user_agent = models.CharField(verbose_name=_('User Agent'), blank=True, max_length=255)

Related

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.

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.

Make django foreignkey varied

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.

List of latest actions per group

I have following models in Django (PostgreSQL):
class Action(models.Model):
actor = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)
verb = models.CharField(max_length=32)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
target_object_id = models.CharField(max_length=255, blank=True, null=True, db_index=True)
class Notification(models.Model):
action = models.ForeignKey(Action, on_delete=models.CASCADE, related_name='notifications')
recipient = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
is_readed = models.BooleanField(default=False)
Can you help me with building notification feed for a user? A query should return the latest actions for the particular recipient, but do not duplicate actions for the same target_object_id.

under same username I can not post?

I am using Django 2.07. In my application after posting the first post, the second post it is not taking a post under the same username (I'm using Django all-auth). At Django admin, it shows me "this username already exits."
this is my profile model:
class Profile(models.Model):
PUBLIC = 'Public'
PRIVATE = 'Private'
INITIATIVE ='Initiative'
PRIVATE_STARTUP = 'Private and Startup'
INITIAL_KEYWORD = (
(PUBLIC, 'Public'),
(PRIVATE, 'Private'),
(INITIATIVE, 'Initiative'),
(PRIVATE_STARTUP, 'Private and Startup'),
)
Type_of_account = models. NullBooleanField('Personal account',
help_text="by default this is Business account")
user_photo = models.ImageField(upload_to='user_image', blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, default=1)
occupation = models.CharField(max_length=400, null=False)
name = models.CharField(max_length=200, null=False, blank=False, default=None)
title = models.CharField(max_length=100, null=True, blank=True)
url = models.URLField(max_length=200, null=True, blank=True)
additional_url = models.URLField(max_length=200, null=True, blank=True )
Headquarter = models.CharField(max_length=1000, null=True, blank=True)
stock_market = models.CharField(max_length=200, null=True, blank=True)
established = models.DateField(auto_now=False, auto_now_add=False, default=None)
investors = RichTextField(null=True, blank=True)
about_details = RichTextField(null=False, blank=False, default=None)
Type_of_company = models.CharField(
max_length=20,
null=True,
blank=True,
choices=INITIAL_KEYWORD,
default=PRIVATE_STARTUP)
This is my main-model.
class MainModel(models.Model):
I_THINK = 'I think'
GOOD_PART = 'Good part'
BAD_PART ='Bad part'
PROTOTYPE = 'Prototype'
FEEDBACK = 'Feedback'
INFO = 'Info'
REVIEW = 'Review'
ASK = 'Ask'
FINACIAL_MARKET = 'Financial market'
INITIAL_KEYWORD_FOR_THOUGHTS = (
(I_THINK, 'I THINK'),
(FEEDBACK, 'FEEDBACK'),
(GOOD_PART, 'GOOD PART'),
(BAD_PART, 'BAD PART'),
(PROTOTYPE, 'PROTOTYPE'),
(INFO, 'INFO'),
(REVIEW, 'REVIEW'),
(ASK, 'ASK'),
(FINACIAL_MARKET, 'FINANCIAL MARKET')
)
user = models.OneToOneField(User, on_delete=models.CASCADE, default=None)
pub_time = models.DateTimeField('Publish time', auto_now=True)
topic = models.CharField(max_length=2000, null=True, blank=True)
##
micro_thought = models.CharField(max_length=200, null=True, blank=True)
Initial_keyword_for_thoughts = models.CharField(
max_length=300,
null=True,
blank=True,
choices=INITIAL_KEYWORD_FOR_THOUGHTS,
default=I_THINK
)
What kind of changes I have to make at main-models user field?
how I can solve this problem?
Thank you for your help.
You are using OneToOne field to relate user to Post. Using OnetoOne field a user can have atmost one post. That is the issue. Change it to ForeignKey relation.
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None)