django - Query the list of objects and their objects field - python

I want to check the MessageState of all the Message in each Threads (i.e. order_threads_message), and if any of the Threads has all the messages hidden then make that Thread as hidden too (/ or else remove it from order_threads_message). I want to do that in the view before passing it to the template. How do I do that? If you didn't get me, please ask. I will be happy to explain. Please help me how to do this in the views. I will be grateful. Thank you.
models.py:
class Thread(models.Model):
subject = models.CharField(max_length=50, blank=True, null=True)
user = models.ManyToManyField(User)
class ThreadState(models.Model):
thread = models.ForeignKey(Thread)
user = models.ForeignKey(User)
thread_hidden = models.BooleanField(default=False)
class Message(models.Model):
thread = models.ForeignKey(Thread)
sender = models.ForeignKey(User)
sent_date = models.DateTimeField(default=datetime.now)
body = models.TextField()
class MessageState(models.Model):
message = models.ForeignKey(Message)
user = models.ForeignKey(User)
read = models.BooleanField(default=False)
message_hidden = models.BooleanField(default=False)
views.py
#login_required
def message(request):
user = request.user
threads = user.thread_set.all()
order_threads_message = threads.annotate(max_sent_date=Max('message__sent_date')).order_by('-max_sent_date')
if order_threads_message.count() > 0:
recent_thread = order_threads_message[0]
if recent_thread.message_set.all().count() > 0:
recent_thread_conversations = recent_thread.message_set.all()
return render(request, 'conversations.html', {
'all_threads':order_threads_message,
'conversations':recent_thread_conversations,
'active': recent_thread.id
})
else:
recent_thread_conversations = 0
return render(request, 'conversations.html', {
'all_threads':order_threads_message,
'conversations':recent_thread_conversations,
'active': recent_thread.id
})
else:
order_threads_message = 0
recent_thread_conversations = 0
return render(request, 'conversations.html', {
'all_threads':order_threads_message,
'conversations':recent_thread_conversations,
})

I have ran this query for the following models:
Models
class Thread(models.Model):
subject = models.CharField(max_length=50, blank=True, null=True)
user = models.ManyToManyField(User)
class ThreadState(models.Model):
thread = models.ForeignKey(Thread)
user = models.ForeignKey(User)
thread_hidden = models.BooleanField(default=False)
class Message(models.Model):
thread = models.ForeignKey(Thread, related_name = 'message_thread')
sender = models.ForeignKey(User)
sent_date = models.DateTimeField(default=datetime.now)
body = models.TextField()
class MessageState(models.Model):
message = models.ForeignKey(Message, related_name='messagestate_message')
user = models.ForeignKey(User)
read = models.BooleanField(default=False)
message_hidden = models.BooleanField(default=False)
Query
Thread.objects.filter(message_thread__in = Message.objects.filter(messagestate_message__in=MessageState.objects.filter(message_hidden=False)))
This query will return the Thread objects if atleast one of its MessageState's message_hidden is False.

Related

Django : access data from serializer after saving it

I want to make an API to allow client to order online.
When the order is validated, I want to send an email to the client to confirm his order.
For that, I need the data that I just created (the order id, the delivery day and the delivery place).
This is my code : models.py :
class memberArea(AbstractBaseUser):
username = models.CharField(max_length=255)
email = models.EmailField(max_length=255, unique=True)
phone = models.TextField()
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
deliveryAddress = models.TextField()
postalCode = models.CharField(max_length=255)
forget = models.TextField(null=True, blank=True)
city = models.CharField(max_length=255)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
class order(models.Model):
user = models.ForeignKey(memberArea, on_delete=models.CASCADE)
comment = models.TextField(null=True, blank=True)
orderDay = models.DateTimeField(auto_now_add=True)
deliveryDay = models.DateField()
deliveryAddress = models.CharField(max_length=255)
state = models.CharField(max_length=255, null=True, blank=True, default="En attente")
price = models.TextField(null=True, blank=True)
response = models.TextField(null=True, blank=True)
class orderDetail(models.Model):
order = models.ForeignKey(order, on_delete=models.CASCADE)
product = models.ForeignKey(product, on_delete=models.CASCADE)
byProduct = models.ForeignKey(byProduct, on_delete=models.CASCADE)
quantity = models.CharField(max_length=255)
serializer.py :
class orderDetailSerializer(serializers.ModelSerializer):
class Meta:
model = orderDetail
fields = '__all__'
read_only_fields = ('order',)
class MakeOrderSerializer(serializers.ModelSerializer):
orderDetail = orderDetailSerializer(many=True)
class Meta:
model = order
fields = ['user', 'comment', 'deliveryAddress', 'deliveryDay', 'orderDetail']
def create(self, validated_data):
order_detail_data = validated_data.pop('orderDetail')
new_order = order.objects.create(**validated_data)
new_order.save()
for product in order_detail_data:
order_detail = orderDetail.objects.create(order=new_order, **product)
return new_order
views.py :
#Make an order
#api_view(['POST'])
def order(request, format=None):
if request.method == 'POST':
serializer = MakeOrderSerializer(data=request.data)
data = {}
if serializer.is_valid():
serializer.save()
data['response'] = "Your order went well"
delivery_date = serializer.data['deliveryDay']
delivery_place = serializer.data['deliveryAddress']
order_id = serializer.data['id']
message = "Thanks for your older.<br/>You will receive your order the <strong>{}</strong><br/>Delivery Place : <strong>{}/strong>.<br/>Order ID: <strong>{}</strong>.<br/>".format('delivery_day', 'delivery_address', 'order_id')
send_mail(
"Validation of your order !",
message,
"myaddress#gmail.com",
["useraddress#gmail.com"],
fail_silently=False,
)
return Response(data)
return Response(serializer.errors)
When I try to use my variables and run my code, this is what I get : Got AttributeError when attempting to get a value for field `orderDetail` on serializer `MakeOrderSerializer`. The serializer field might be named incorrectly and not match any attribute or key on the `order` instance. Original exception text was: 'order' object has no attribute 'orderDetail'.
Thanks by advance for helping me.
To access data from serializer you can use serializer.data['deliveryDate']. Similarly you can access serializer.data['orderDetail'] it will return a list, then you can iterate over it to access your other data.

Problems with implementing inviting feature

I am working on the social network project and want to create feature that will give me opportunity to invite users to communities with invite url(UUID).Who can explain how to do that, i have tried to do that with context processors,but it doesn't work
models.py
class Room(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, null=True, blank=True)
description = models.TextField(max_length=500)
students = models.ManyToManyField(User,related_name='room_students',blank=True)
created = models.DateTimeField(default=timezone.now)
subjects = models.ManyToManyField(Subject,related_name='room_subjects',blank=True)
stream_time = models.TimeField()
max_students_amount = models.PositiveIntegerField()
room_type = models.CharField(max_length=10,choices=TYPES)
invite_url = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
is_active = models.BooleanField(default=True)
views.py
#login_required
def submit_invite(request,room):
invite_url = request.get.GET['key']
room = get_object_or_404(Room,slug=room)
user = request.user
if room.invite_url != invite_url:
return HttpResponseNotFound
room.students.add(user)
return room.get_absolute_url()
#login_required
def join_room(request,room):
room = get_object_or_404(Room,slug=room)
user = request.user
room.students.add(user)
return HttpResponse(room.students.count())
urls.py
path('rooms/<room>/invite?key=<invite_url>/',submit_invite,name='sumbit_invite'),

Cannot retrieve specific data from django?

I'm trying to create a simple page containing 1 video and as many comments as it has and each comment replies
I basically created three models, one for Video, one for comment and one for reply. then I tried to retrieve the data in the view file.
I successfully retrieved video and comments but failed to retrieve replies of each comment.
I'm using django 1.10.4
models.py
class Video(models.Model):
title = models.CharField(max_length=120)
embed_code = models.CharField(max_length=500)
slug = models.SlugField(null=True, blank=True)
category = models.ForeignKey("Category", null=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
active = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
free_preview = models.BooleanField(default=False)
share_message = models.CharField(max_length=150, default=default_share_message)
objects = models.Manager()
# activemodel = ActiveModel()
featuresandactive = Features()
class Meta:
unique_together = ('slug', 'category')
def __str__(self):
return self.title
def get_absolute_url(self):
try:
return reverse('video_detail', kwargs={'vid_slug':self.slug, 'cat_slug':self.category.slug})
except:
return "/"
class Comment(models.Model):
user = models.ForeignKey(MyUser)
path = models.CharField(max_length=350)
video = models.ForeignKey(Video, null=True, blank=True)
text = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
Timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
active = models.BooleanField(default=True)
objects = CommentManager()
def __str__(self):
return self.text
class Reply(models.Model):
user = models.ForeignKey(MyUser)
comment = models.ForeignKey(Comment,null=True, blank=True)
text = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
Timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
active = models.BooleanField(default=True)
objects = ReplyManager()
def __str__(self):
return self.text
views.py
def video_detail(request, cat_slug, vid_slug):
cat = Category.objects.get(slug=cat_slug)
comments = Comment.objects.filter(video=obj)
replys = Reply.objects.filter(comment=comments)
context = {
"cat": cat,
"obj":obj,
"comments":comments,
"replys":replys,
}
return render(request, 'video_detail.html', context)
this is another view.py
I tried this also but didn't work
def video_detail(request, cat_slug, vid_slug):
cat = Category.objects.get(slug=cat_slug)
obj = Video.objects.get(slug=vid_slug)
comments = obj.comment_set.all()
replys = comments.reply_set.all()
context = {
"cat": cat,
"obj":obj,
"comments":comments,
"replys":replys
}
return render(request, 'video_detail.html', context)
When you do this:
comments = Comment.objects.filter(video=obj)
'comments' contains a QuerySet. What you want to do next is ask for every Reply with a comment that's on that QuerySet, instead of comparing using '=':
replies = Reply.objects.filter(comment__in=comments)
relevant documentation: https://docs.djangoproject.com/en/dev/ref/models/querysets/#in
edit: changed it to 'replies' instead of 'replys'
edit2: added docs link

expected string or buffer: Private Messages App

I am trying to make Private Message App for my website on django.
Models.py:
class Message(models.Model):
sender = models.ForeignKey(User, related_name='sender')
recipient = models.ForeignKey(User, related_name='recipient')
sent_date = models.DateTimeField(blank=True, null=True)
title = models.CharField(max_length=70, default='Без теми', blank=True, null=True)
body = models.TextField(max_length=10000)
def __str__(self):
return self.title
class Meta:
verbose_name = 'повідомлення'
verbose_name_plural = 'Повідомлення'
Views.py:
#login_required
def write(request):
context = {}
context.update(csrf(request))
context['form'] = WriteMessage()
if request.POST:
write_form = WriteMessage(request.POST)
if write_form.is_valid():
cd = write_form.cleaned_data
if User.objects.filter(username=cd['recipient']).exists():
message = Message(sender = request.user, recipient=User.objects.get(username = cd['recipient']), title=cd['title'], body=cd['body'], sent_date=datetime.now)
message.save()
return redirect('/inbox/')
else:
context['errors'] = ["Not found user with this username"]
return render(request, 'send_message.html', context)
else:
return render(request, 'send_message.html', context)
And when I try to send the message, I get the error: expected string or buffer. But, when I send message from admin page - it works wonderful.
What I must do? Help me, please. Thanks.
My solution is replace sent_date = models.DateTimeField(blank=True, null=True) for sent_date = models.DateTimeField(auto_now_add=True) and deleting sent_date=datetime.now from creating new object in views.py
It seems, that trouble was in different types of data in DateField into models.py and datetime module...

Get logged in user and value of another model - Tastypie

Models:
class Applicant_Skill(models.Model):
user = models.ForeignKey(User)
#applicant = models.ForeignKey(Applicant)
skill = models.ForeignKey('skills_layer.Skill')
active = models.BooleanField(default=True)
class Job_Posting(models.Model):
company = models.ForeignKey('companies_layer.Company', default=-1)
job_posted_by = models.ForeignKey(User, default=-1)
job_title = models.CharField(max_length=100)
job_summary = HTMLField(blank=True)
job_details = HTMLField(blank=True)
no_of_openings = models.IntegerField(default=0)
tags = models.CharField(max_length=200)
experience_min = models.IntegerField(default=0)
experience_max = models.IntegerField(default=0)
job_location = models.ForeignKey('meta_data_layer.Location', blank=True, null=True)
qualification = models.ForeignKey('meta_data_layer.Qualification', default=-1)
specialization = models.ForeignKey('meta_data_layer.Specialization', default=-1)
nationality = models.ForeignKey('meta_data_layer.Nationality', default=-1)
live = models.BooleanField(default=True)
closing_date = models.DateField(default=datetime.date.today())
auto_renew = models.BooleanField(default=False)
active = models.BooleanField(default=True)
class Meta:
verbose_name = "job posting"
def __str__(self):
return self.job_title
Resource:
from tastypie.resources import ModelResource
from job_posting_layer.models import Job_Posting
from companies_layer.models import Company
from django.contrib.auth.models import User
import meta_data_layer
from tastypie import fields
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
def dehydrate(self, bundle):
bundle.data['logged_user_id'] = bundle.request.user.id
return bundle
class JobListingResource(ModelResource):
#company = fields.ForeignKey(CompanyResource,'company', full=True)
#job_posted_by = fields.ForeignKey(UserResource,'job_posted_by', full=True)
company_name = fields.CharField(attribute="company__company_name", null=True)
company_id = fields.CharField(attribute="company__id", null=True)
user_first_name = fields.CharField(attribute="job_posted_by__first_name", null=True)
user_last_name = fields.CharField(attribute="job_posted_by__last_name", null=True)
user_id = fields.CharField(attribute="job_posted_by__id", null=True)
job_location = fields.CharField(attribute="job_location__location_name", null=True)
job_city = fields.CharField(attribute="job_location__city", null=True)
qualification = fields.CharField(attribute="qualification__qualification_degree", null=True)
specialization = fields.CharField(attribute="specialization__specialization_course", null=True)
nationality = fields.CharField(attribute="nationality__country_name", null=True)
class Meta:
queryset = Job_Posting.objects.all()
resource_name = 'jobs'
Today is the 1st day I am trying Tastypie so please be kind with me :(
The JobListingResource returns all the Job Listings. But I want to get only those Job Listings for which the Tags column contains values from the skill column of the logged in user.
Eg: If user "A" has logged in and has the following skills "python,django,jquery". I want the JobListingResource to return only those records which contains [python/django/jquery] in the tags column.
I'm assuming you know how to do the queries and just need to know where to do it in Tastypie. In your JobListResource override as follows:
def get_object_list(self, request):
# get all the jobs according to the queryset in Meta
base = super(JobListingResource, self).get_object_list(request)
# and add a filter so only users ones appear
user = request.user
skills = query to get all the skills for the user
return base.filter(filter to apply to JobPosting to only return jobs matching skills list)

Categories