Am having a challenge to get users post on their timeline and I would appreciate if anyone could help me. I keep coming against this error(QuerySet' object has no attribute 'posts') when ever filter through the post object. I wonder what am missing out on here ? here is my model for post.
class Post(models.Model):
description = models.CharField(max_length=5000, blank=True)
pic = models.ImageField(upload_to='path/post/img' ,blank=True)
date_posted = models.DateTimeField(auto_now_add=True)
user_name = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
users = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name="users")
tags = models.CharField(max_length=100, blank=True)
here is my view for users account since i want every user to have their post on their timeline.
def account_view(request, *args, **kwargs):
"""
- Logic here is kind of tricky
is_self
is_friend
-1: NO_REQUEST_SENT
0: THEM_SENT_TO_YOU
1: YOU_SENT_TO_THEM
"""
context = {}
user_id = kwargs.get("user_id")
try:
account = User.objects.get(pk=user_id)
except:
return HttpResponse("Something went wrong.")
if account:
context['id'] = account.id
context['username'] = account.username
context['bio'] = account.bio
context['get_full_name'] = account.get_full_name
context['email'] = account.email
context['profile_pic'] = account.profile_pic.url
context['cover_image'] = account.cover_image.url
context['city'] = account.city
context['country'] = account.country
context['gender'] = account.gender
context['hide_email'] = account.hide_email
try:
post_list = Post.objects.filter(user_name=account)
except Post.DoesNotExist:
post_list = Post(user_name=account)
save.post_list()
posts = post_list.posts.all()
context['posts'] = posts
try:
friend_list = FriendList.objects.get(user=account)
except FriendList.DoesNotExist:
friend_list = FriendList(user=account)
friend_list.save()
friends = friend_list.friends.all()
context['friends'] = friends
You have to change to: posts = post_list.all()
Related
Model.py
class Branch(models.Model): # Branch Master
status_type = (
("a",'Active'),
("d",'Deactive'),
)
name = models.CharField(max_length=100, unique=True)
suffix = models.CharField(max_length=8, unique=True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.name
class Vendor(models.Model):
status_type = (
("a",'Active'),
("d",'Deactive'),
)
branch = models.ManyToManyField(Branch)
company = models.CharField(max_length=200)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=11, unique = True)
email = models.EmailField(max_length=254, unique = True)
gst = models.CharField(max_length=15, unique = True)
pan_no = models.CharField(max_length=10, unique = True)
add_1 = models.CharField(max_length=50, null=True, blank = True)
add_2 = models.CharField(max_length=50, null=True, blank = True)
add_3 = models.CharField(max_length=50, null=True, blank = True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.company
form.py
i want save like created_by field
class VendorForm(ModelForm):
class Meta:
model = Vendor
fields = 'all'
exclude = ['created_by', 'branch']
widgets = {
'company':forms.TextInput(attrs={'class':'form-control'}),
'name':forms.TextInput(attrs={'class':'form-control'}),
'phone':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),
'gst':forms.TextInput(attrs={'class':'form-control'}),
'pan_no':forms.TextInput(attrs={'class':'form-control'}),
'add_1':forms.TextInput(attrs={'class':'form-control'}),
'add_2':forms.TextInput(attrs={'class':'form-control'}),
'add_3':forms.TextInput(attrs={'class':'form-control'}),
'Remark':forms.Textarea(attrs={'class':'form-control','rows':'2'}),
'status':forms.Select(attrs={'class':'form-control'}),
}
Views.py
I have pass branch in session.
I want to save with branch which is many to many field
def Add_Vendor(request): # for vendor add
msg = ""
msg_type = ""
branch_id = request.session['branch_id']
branch_data = Branch.objects.get(id = branch_id)
form = ""
if request.method == "POST":
try:
form = VendorForm(request.POST)
if form.is_valid:
vendor_add = form.save(commit=False)
vendor_add.created_by = request.user
vendor_add.instance.branch = branch_data.id
vendor_add.save()
form.save_m2m() # for m to m field save
msg_type = "success"
msg = "Vendor Added."
form = VendorForm(initial={'branch':branch_id})
except:
msg_type = "error"
msg = str(form.errors)
print(msg)
else:
form = VendorForm(initial={'branch':branch_id})
context = {
'form':form,
'branch_data':branch_data,
'msg_type':msg_type,
'msg':msg,
'btn_type':'fa fa-regular fa-plus',
'form_title':'Vendor Form',
'tree_main_title':'Vendor',
'v_url':'vendor_page',
'tree_title':'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html',context)
I would advise not to work with commit=False in the first place:
def Add_Vendor(request): # for vendor add
branch_id = request.session['branch_id']
branch_data = get_object_or_404(Branch, pk=branch_id)
if request.method == 'POST':
form = VendorForm(request.POST, request.FILES)
if form.is_valid():
form.instance.created_by = request.user
form.instance.branch = branch_data.id
vendor_add = form.save()
vendor_add.branch.add(branch_data)
return redirect('name-of-some-view')
else:
form = VendorForm()
context = {
'form': form,
'branch_data': branch_data,
'btn_type': 'fa fa-regular fa-plus',
'form_title': 'Vendor Form',
'tree_main_title': 'Vendor',
'v_url': 'vendor_page',
'tree_title': 'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html', context)
You can simplify your form by automatically adding form-control to each widget:
class VendorForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
attrs = field.widget.attrs
attrs['class'] = attrs.get('class', '') + ' form-control'
class Meta:
model = Vendor
exclude = ['created_by', 'branch']
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can set a field editable=False [Django-doc]. Then the field does not show up in the ModelForms and ModelAdmins by default. In this case for example with created_by.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Please do not pass messages manually to the template. Django has the messages framework [Django-doc], which allows to add messages to the request, which will then be delivered the next time a template renders these messages. This makes delivering multiple messages convenient, as well as setting different log levels to the messages.
I have a function in which I have to, among other things, pass to the template the ids of the users who conducted the correspondence, but I get an error in the line:
pk_list = messages.values('user_from__pk').distinct()
views.py:
def send_chat(request):
resp = {}
User = get_user_model()
if request.method == 'POST':
post =request.POST
u_from = UserModel.objects.get(id=post['user_from'])
u_to = UserModel.objects.get(id=post['user_to'])
messages = request.user.received.all()
pk_list = messages.values('user_from__pk').distinct()
correspondents = get_user_model().objects.filter(pk__in=list(pk_list))
insert = chatMessages(user_from=u_from,user_to=u_to,message=post['message'],correspondents=correspondents)
try:
insert.save()
resp['status'] = 'success'
except Exception as ex:
resp['status'] = 'failed'
resp['mesg'] = ex
else:
resp['status'] = 'failed'
return HttpResponse(json.dumps(resp), content_type="application/json")
models.py:
class chatMessages(models.Model):
user_from = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="sent")
user_to = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="received")
message = models.TextField()
date_created = models.DateTimeField(default=timezone.now)
correspondents = models.ForeignKey(User,
on_delete=models.CASCADE,related_name="correspondents", null=True)
def __str__(self):
return self.message
Error:
TypeError: Field 'id' expected a number but got {'user_from__pk': 1}.
how can I fix this error?
problem is here:
pk_list = messages.values('user_from__pk').distinct()
queryset.values give you a list of dictionaries. in your case [{'user_from__pk': pk1}, {'user_from__pk': pk2},... e.t.c.]
more here: https://docs.djangoproject.com/en/4.1/ref/models/querysets/#values
And you need values_list.
pk_list = messages.values_list('user_from__pk', flat=True).distinct()
To avoid joins - you can do:
pk_list = messages.values_list('user_from_pk', flat=True).distinct()
more here:
https://docs.djangoproject.com/en/4.1/ref/models/querysets/#values-list
How Do I get id of to_user from the below model:
class Friend(models.Model):
status = models.CharField(max_length=10)
from_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name = 'from_user')
to_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="to_user")
date_modified = models.DateTimeField(auto_now=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def create(self,request, **kwargs, ):
friend = self.create(from_user_id=request.user.id, status="Pending")
return friend
class Meta:
unique_together = (('from_user', 'to_user'),)
def __str__(self):
return self.to_user.email
my view :
def accept_friend_request(request, uidb64, status):
"""Accept button will lead to entry in database as accepted and reject button will lead to entry in database as rejected based on status flag"""
Friend.status = "pending"
try:
uid = urlsafe_base64_decode(uidb64)
friend_user = User.objects.filter(id=Friend.to_user.id)
f = Friend.objects.filter(friend_id = friend_user)
if f:
f.status=status
f.save()
f.status = "accepted"
return render(request, 'users/friend_list.html', {"uidb64": uid, "status": status})
else:
f.status = "rejected"
f.save()
return render(request, 'users/friend_list.html', {'uidb64':uid, 'status':status})
except AttributeError:
return render(request, 'blog/base.html')
I cannot retrieve the friend_user = User.objects.filter(id=Friend.to_user.id)
Thanking you in advance,
Friend is a model class, and you need an instance of such class in order to relate it to another model instance as a foreign relationship.
For example:
friend_instance = Friend.objects.get(name='Madeleaine')
...
friend_user = friend_instance.to_user.id
I have the following models that I need to create a form which allows for the updating of an existing Response (generated previously with a slug and then emailed to the respondent) and the creation of a Rating for each CV in CV.objects.all(). What's the easiest way to do this in Django. Currently I have a class-based UpdateView for Response and that's it.
class Response(models.Model):
first_name = models.CharField(max_length=200, null=True, blank=True)
last_name = models.CharField(max_length=200, null=True, blank=True)
email = models.EmailField(max_length=254)
slug = models.SlugField(max_length=32)
submited = models.BooleanField(default=False)
submit_time = models.DateTimeField(null=True, blank=True)
creation_time = models.DateTimeField(auto_now_add=True)
class CV(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to=content_file_name)
class Rating(models.Model):
cid = models.ForeignKey('CV')
rid = models.ForeignKey('Response')
score = models.IntegerField()
comment = models.TextField()
I eventually worked out how to do this. My code was as follows in case anyone is interested.
def add_response(request):
CVs = CV.objects.all()
if request.method == "POST":
ResForm = ResponseForm(request.POST, instance=Response())
RatForms = [RatingForm(request.POST, prefix=str(cv.id), instance=Rating(cid=cv)) for cv in CVs]
if ResForm.is_valid() and all([rf.is_valid() for rf in RatForms]):
new_response = ResForm.save(commit=False)
new_response.submit_time = datetime.now()
new_response.submited = True
new_response.save()
for rf in RatForms:
new_rating = rf.save(commit=False)
new_rating.rid = new_response
new_rating.save()
return HttpResponseRedirect('/thanks/')
else:
for i, _ in enumerate(RatForms):
RatForms[i].cv = CV.objects.filter(id=int(RatForms[i].prefix))[0]
print RatForms[i].cv
return render(request, 'response.html', {'response_form': ResForm, 'rating_forms': RatForms})
else:
ResForm = ResponseForm(instance=Response())
RatForms = [RatingForm(prefix=str(cv.id), instance=Rating(cid=cv)) for cv in CVs]
for i, _ in enumerate(RatForms):
RatForms[i].cv = CV.objects.filter(id=int(RatForms[i].prefix))[0]
print RatForms[i].cv
return render(request, 'response.html', {'response_form': ResForm, 'rating_forms': RatForms})
i have pasted my code along with stack trace at .. https://gist.github.com/2199510
my models.py
class Roles(models.Model):
role = models.CharField(max_length=32)
def __unicode__(self):
return self.role
class Player(models.Model):
first_name = models.CharField(max_length=32)
last_name = models.CharField(max_length=32)
#name = models.CharField(max_length=32)
team = models.ForeignKey(Team)
role = models.ManyToManyField(Roles)
preffered_position = models.IntegerField(max_length=3,choices=zip(range(1,12),range(1,12)) , default=1)
status = models.BooleanField(default=True)
#career statistics
best_batting = models.IntegerField(max_length=6, default=0)
best_bowling = models.CharField(max_length=6, default=0)
#total batting statistics
score = models.IntegerField(max_length=6, default=0)
balls = models.IntegerField(max_length=6, default=0)
#total bowling statistics
overs = models.IntegerField(max_length=6, default=0)
wickets = models.IntegerField(max_length=6, default=0)
#total fielding statistics
catches = models.IntegerField(max_length=6, default=0)
def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)
my forms.py
class PlayerForm(forms.Form):
first_name = forms.CharField()
last_name = forms.CharField()
role = forms.ModelMultipleChoiceField(
Roles.objects.all(),
widget=CheckboxSelectMultiple
)
my views.py
def add_player(request, team_id):
template = get_template('cricket/addplayer.html')
loggedinuser = request.user
userteam = Team.objects.get(owner=loggedinuser)
currentteam = Team.objects.get(id=team_id)
#now on to permissions .. if userteam = currentteam, the display form, otherwise display error "Permission denied"
if userteam == currentteam:
if request.method == 'POST':
form = PlayerForm(request.POST)
if form.is_valid():
Player.objects.create(
first_name = form.cleaned_data['first_name'],
last_name = form.cleaned_data['last_name'],
team = Team.objects.get(id=team_id),
role = form.cleaned_data['role'],
)
return HttpResponseRedirect('/team/%s/' % team_id)
else:
form = PlayerForm
page_vars = Context({
'form': form,
'loggedinuser': loggedinuser,
'team': userteam,
})
crsfcontext = RequestContext(request, page_vars)
output = template.render(crsfcontext)
return HttpResponse(output)
else:
error = "Permission Denied: You cannot add player to " + str(currentteam.name)
page_vars = Context({
'loggedinuser': loggedinuser,
'error': error,
})
crsfcontext = RequestContext(request, page_vars)
output = template.render(crsfcontext)
return HttpResponse(output)
if somebody could tell me where and what i am doing wrong, that would be of great help.
//yousuf
As the error message states, you can't pass role (or any ManyToMany field) as a keyword in the model instantiation call. You need to instantiate and save your model first, then add one or more roles with player.roles.add(my_role).