I have two models, ChatBox and Message. I want to loop through all chats and display them, and I want to display a count of unseen messages (Message model is in a foreign key relation) for each chat.
Could anyone please help me to do this since I ve been strugling with it for few hours.
Firstly I wanted to pass each object from the loop to django filters/tags and add a count of unseen messages to it, but I got advised to use objects.annotation. However, i can not find ways to implement none of these.
Here is my view that displays inbox:
class InboxView(LoginRequiredMixin, ListView):
model = ChatBox
template_name = 'chat/inbox.html'
def get_queryset(self):
# getting all chats for a request.user
object_list = ChatBox.objects.filter(Q(user1=self.request.user) \
| Q(user2=self.request.user)).all()
return object_list
And here are my models:
class ChatBox(models.Model):
user1 = models.ForeignKey(CustomUser,
on_delete=models.CASCADE, related_name='user1')
user2 = models.ForeignKey(CustomUser,
on_delete=models.CASCADE, related_name='user2')
slug = models.SlugField(_("Slug"), max_length=255, unique=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Message(models.Model):
chat = models.ForeignKey(ChatBox, on_delete=models.CASCADE)
sender = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='sender')
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
seen = models.BooleanField(default=False)
Related
error image
I'm using the model and I keep running into problems with many to many. At first, I made it without giving an id value, but it seems that the id value is not entered, so when I put the id value directly, the same problem as above occurs. But in the Post model below, the same form of likes is used. Why?
from django.db import models
# from django.contrib.auth.models import User
from django.conf import settings
# from server.apps.user.models import Profile
# Create your models here.
class Clothes(models.Model):
CATEGORYS =[
(0, '상의'), #상의
(1, '하의'), #하의
(2, '아우터'), #아우터
(3, '신발'), #신발
(4, '악세사리'), #악세사리
]
category = models.IntegerField(default=0,choices=CATEGORYS)
id = models.IntegerField(primary_key=True)
img = models.ImageField(upload_to='main/images/clothes/%Y/%m/%d')
save = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Pickitems', blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
buying = models.TextField(null=True, blank=True)
def __str__(self):
return f'{self.id}: {self.category}'
#pk가 존재하지 않는것 같음.
# class SavePeople(models.Model):
class Post(models.Model):
main_img = models.ImageField(upload_to='main/images/post/%Y/%m/%d')
title = models.CharField(max_length=100)
content = models.TextField()
private = models.BooleanField(default=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
clothes = models.ManyToManyField(Clothes,related_name='Clothes')
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Likes', blank=True)
def __str__(self):
return f'{self.pk}: {self.title}'
def get_absolute_url(self):
return f'/community/'
#이거 나중에 detail page로 바꿔주세요
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
update_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'({self.author}) {self.post.title} : {self.content}'
class Commu(models.Model):
COMMU_CHOICES = [
('buying', 'buying'), #공동구매
('openrun', 'openrun'), #오픈런
('question', 'question'), #고민방
]
category = models.CharField(max_length=20, choices=COMMU_CHOICES)
img = models.ImageField(upload_to='main/images/commu/%Y/%m/%d', null=True, blank=True)
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return f'{self.pk}: {self.title}'
def get_absolute_url(self):
return f'/community/commu'
I added the code saves= models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='Save', blank=True) to the Clothes model to make a save of Clothes in the same way as the likes of the Post model, but an error like the attached picture is displayed. occurred. When I searched, it seemed that the pk value did not exist.
The issue is the id field that you explicitly provided, Django itself creates an id field as a primary key for each model if you don't specify one. So, it is not necessary to add it to the model. Kindly remove it through the Clothes model and run migration commands.
And it doesn't give in case of likes since there is no extra field id in Post model unlike that of Clothes.
Note: Models in Django doesn't require s to be added as suffix, as it is automatically done, so you may change Clothes to Cloth.
Problem: I have Two Tables Users and Users Group and in front end on
request of that particular page need to send all data from both the
table together, as there is specific drop down to show them both, and after done with the operation of that page data will get back in POST request (current models structures is given below), i am not getting how do i make connection in all these three tables so that it will get managed, Please let me know.
Model: User.py
class Users(AbstractBaseUser):
vendor_name = models.ForeignKey(Vendor, 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)
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()
Model: UserGroup.py
class UserGroup(models.Model):
vendor_id = models.ForeignKey(Vendor, on_delete=models.CASCADE, default=None, null=True)
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
users = models.ManyToManyField(Users)
def __str__(self):
return self.name
Model: Rules.py
class Rules(models.Model):
vendor_id = models.ForeignKey(Vendor, on_delete=models.CASCADE, default=None, null=True)
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
# Here i need to mention the code for field where i can store the combined value of User and UserGroup [selected from the dropdown].
def __str__(self):
return self.name
Need Solution:
How do i code in View to fetch the data of Two tables to send them for DropDown. {GET Request}
How will i store the values for the same together in Rules Table { As i said DropDown consist both values and can be selected all
together. }
The Structure of the Model {with the required Changes}.
there is no out of the box solution for that. I can advise to seprate this dropdown into two. First with UserGroup, second with User. You can fill user dropdown based on selected UserGroup with ajax or htmx -> htmx value-select
In your model Rules (should be Rule)
add fields:
user = models.ForeignKey(Users, on_delete=models.CASCADE)
group = models.ForeignKey(UserGroup, on_delete=models.CASCADE)
if there can be only one rule per Users(this should also be User)/UserGroup add unique_toigether to model Rules:
unique_together = ['user', 'group']
django docs unique_together
i'm new with Django and as I read the code, I don't understand the message_set attribute of Django model(called Room):
def room(request, pk):
room = Room.objects.get(id=pk)
**room_messages = room.message_set.all()**
participants = room.participants.all()
portion of Models:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(
User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
If you define a ForeignKey from Message to Room, Django will add a relation in reverse to the from the Room model to its related Messages. By default this relation is named modelname_set with modelname the name of the origin of the model. You can specify another name by overriding the related_name=… parameter [Django-doc].
If you thus access the relation in reverse, you get all Message objects with room as there room, an equivalent query to room.message_set.all() is thus Message.objects.filter(room=room).
I am trying to make a user panel in which each user's profile info (like avatar, joined date, etc.) are being displayed along with their posts. Here is the view that render the threads:
def topic(request, topic_id):
"""Listing of posts in a thread."""
posts = Post.objects.select_related('creator') \
.filter(topic=topic_id).order_by("created")
posts = mk_paginator(request, posts, DJANGO_SIMPLE_FORUM_REPLIES_PER_PAGE)
topic = Topic.objects.get(pk=topic_id)
topic.visits += 1
topic.save()
return render_to_response("myforum/topic.html", add_csrf(request, posts=posts, pk=topic_id,
topic=topic), context_instance=RequestContext(request))
The Topic model is:
class Topic(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(max_length=10000, null=True)
forum = models.ForeignKey(Forum)
created = models.DateTimeField()
creator = models.ForeignKey(User, blank=True, null=True)
visits = models.IntegerField(default = 0)
And the UserProfile model:
class UserProfile(models.Model):
username = models.OneToOneField(User)
name = models.CharField(max_length=30, blank=True)
city = models.CharField(max_length=30, blank=True)
country = models.CharField(
max_length=20, choices= COUTNRY_CHOICES, blank=True)
avatar = ImageWithThumbsField(), upload_to='images', sizes=((32,32),(150,150),(200,200)), blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, blank=True)
The problem is how best to join these two tables so that userprofile fields can be displayed in topic.html along with username?
Add them to context since you already have a database relation Users and Topics.
# add this to context
topic = Topic.objects.get(pk=topic_id)
creator = topic.creator.get().profile # This pulls the user object from creator field
context['creator'] = creator # Add to context
Now you can use the 'creator' context to pull fields
<h1>{{ creator.name }}</h1>
as for the avatar, if you have your media root set in settings you simply use an
<img src="/media/images/{{ creator.avatar }}">
Oh and also you can save alot of time by using ListView and DetailView part of Django's class based views.
Sorry forgot to mention you should add a related name to your one to one,
username = OneToOneField(User, related_name='profile')
I am working on a ride share application. I need help on designing the models for private messages.
I have designed the below models, its look like complex in querying them in views. can You guys specify a better and easy one.
class Ride(models.Model):
type = models.BooleanField(default=False)
add_source = models.ForeignKey(Address, related_name='source')
add_destination = models.ForeignKey(Address, related_name='destination')
ride_startDateTime = models.DateTimeField(default= datetime.datetime.now, blank=True)
ride_startPref = models.CharField(max_length=10, choices=CHOICES, default='None')
class Conversation(models.Model):
ride_id = models.ForeignKey(Ride)
class Messages(models.Model):
conversation_id = models.ForeignKey(Conversation)
ride_id = models.ForeignKey(Ride)
sender_id = models.ForeignKey(User, related_name='sender')
receiver_id = models.ForeignKey(User, related_name='receiver')
Content = models.TextField(max_length=1000,blank=True)
timestamp = models.DateTimeField(default= datetime.datetime.now, blank=True)
status = models.CharField(max_length=10,blank=True)
User model is django inbuilt.
Please consider the following use cases:
1) A Conversation has to integrate with Ride,
For Ex: User X is a owner of ride 3, User Y can contact X for this ride(3), then the new conversation id(77) will be generated. After that whatever messages sent between them should be under the same conversation id(77).
If another user Z is trying to contact the user X for the same ride 3, then a new conversation ID(33) has to generated.
2) If the user X having another ride called 4, then if user Y contact the User X through the other ride means, it has to generate new conversation id(99) and all the messages sent between them on the ride should come under the same conversation id(99).
Compare with:
class Ride(models.Model):
type = models.BooleanField(default=False)
source_address = models.ForeignKey(Address, related_name='rides_from')
destination_address = models.ForeignKey(Address, related_name='rides_to')
started_at = models.DateTimeField(auto_now_add=True)
start_pref = models.CharField(max_length=10, choices=CHOICES, default='None')
class Conversation(models.Model):
ride = models.ForeignKey(Ride)
user1 = models.ForeignKey(User, related_name='conversations_as_user1')
user2 = models.ForeignKey(User, related_name='conversations_as_user2')
class Message(models.Model):
conversation = models.ForeignKey(Conversation)
posted_by = models.ForeignKey(User, related_name='messages')
content = models.TextField(max_length=1000)
posted_at = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=10,blank=True)
Keep in mind that whenever wither sender or receiver is deleting a message, it is deleted for both of them.