Problem with set value in view and template - django

I want to create a list where the user can give titles to his list in which he selects in which category he should be, this is how the model looks like
class UserListAnime(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
anime = models.ManyToManyField(Anime, through='ListAnime')
class Anime(models.Model):
title = models.CharField(max_length=200)
slug = extension_fields.AutoSlugField(populate_from='title', blank=True)
class ListAnime(models.Model):
LIST_CHOICES = (
(WATCHING, 'Oglądam'),
(PLANNING, 'Planuję'),
(COMPLETED, 'Ukończone'),
(DROPPED, 'Porzucone'),
(ONHOLD, 'Wstrzymane'),
(MISSING, 'Pomijam'),
)
user = models.ForeignKey(UserListAnime, on_delete=models.CASCADE, null=True, blank=True)
anime = models.ForeignKey(Anime, on_delete=models.CASCADE, null=True, blank=True)
type = models.CharField(max_length=30, choices=LIST_CHOICES, null=False, blank=False)
In the view I only have to take a list of the user and I have displayed it but I want it to be filtered through the type in ListAnime
def ListAnimeView(request, pk, username):
list_anime = UserListAnime.objects.filter(user__pk=pk, user__username=username,
listanime__type='ogladam',
anime__listanime__type='ogladam').all()
context = locals()
and html looks like
{% for list in list_anime.anime.all %}
{{ list }}
{% endfor %}
My question is how to extract all records when type = LIST_CHOICES and show this in html
EDIT: SOLVED just need change in view from UserListAnime,objects.. to ListAnime.objects
and in html should be
{% for list in list_anime %}
{{ list.anime }}
{% endfor %}

I don't know exactly what are you trying to achieve. Do you want to get a list of ListAnime entities given a user, and get only which are of type 'ogladam'?
def listAnimeView(request, pk):
list_anime = ListAnime.objects.filter(user__user_id=pk, type='ogladam')
return render(request, 'template-name', context=['list_anime': list_anime])'

Related

django eccomerce prodcut name not showing in file

i am creating a new django eccomorce website now in product detail page here is my code
the problem is i cant see product name correct in html page problem with first()
when i use first then only product name showing but all products have same name i have 8 producs in my page eight product name same to first just like overwriting also i cant use for loop with first()
i will add some pics
urls.py
path('collection/<str:cate_slug>/<str:prod_slug>',views.product_view,name="productview"),
views.py
def product_view(request,cate_slug,prod_slug):
if (Category.objects.filter(slug=cate_slug, status=0)):
if (Products.objects.filter(slug=prod_slug, status=0)):
products = Products.objects.filter(slug=prod_slug, status=0).first()
context = {'products':products}
else:
messages.error(request,"no such product found")
return redirect("collection")
else:
messages.error(request,"no such category found")
return redirect("collection")
return render(request,"product_view.html",context)
models.py
class Products(models.Model):
category = models.ForeignKey(Category,on_delete=models.CASCADE)
slug = models.CharField(max_length=150, null=False, blank=False)
product_name = models.CharField(max_length=150, null=False, blank=False)
product_image = models.ImageField( upload_to=get_image,null=True,blank=True)
description = models.TextField(max_length=500,null=False,blank=False)
original_price = models.IntegerField(null=False,blank=False)
selling_price = models.IntegerField(null=False,blank=False)
status = models.BooleanField(default=False,help_text="0=default , 1=Hidden")
trending = models.BooleanField(default=False,help_text="0=default , 1=Trending")
meta_title = models.CharField(max_length=150,null=False,blank=False)
meta_keyword = models.CharField(max_length=150,null=False,blank=False)
meta_description = models.CharField(max_length=400,null=False,blank=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.product_name
productview.html
{% block content %}
<h1>{{ products.product_name }} </h1>
{% endblock %}
i just want correct product name for every category i stucked here in morning helping are appreciated thank you all for helping till now
I think you need to loop through your produckts:
{% for product in products %}
<h1>{{ product.product_name }}</h1>
{% endfor %}
view:
def product_view(request,cate_slug,prod_slug):
if (Category.objects.filter(slug=cate_slug, status=0).exists()):
if (Products.objects.filter(slug=prod_slug, status=0).exists()):
products = Products.objects.filter(slug=prod_slug, status=0)
context = {'products':products}
else:
messages.error(request,"no such product found")
return redirect("collection")
else:
messages.error(request,"no such category found")
return redirect("collection")
return render(request,"product_view.html",context)
Note that usually the model name is singular, so it should be class Products(models.Model):

How to add condition to a manytomany relationship

I'm a little new to Django, so my question may be basic, but bare with me. Let's say I'm sharing my posts with some of my friends (who are manytomany relation with the post), but also giving an extra condition for whether they can comment on it, or not. This condition, together with the name of the user to be shared with are submitted through a forum. Now my problem is that I don't know how/where to save this condition. I will show you some of my code.
Models.py
class Task(models.Model):
name = models.CharField(max_length=50)
text = models.TextField()
deadline = models.DateTimeField()
created = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='taskset')
shared = models.ManyToManyField(User, blank=True, related_name = 'shared_list')
def __str__(self):
return f"{self.name}-{self.user.username}"
class Comment(models.Model):
text = models.TextField()
task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='comments')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')
created = models.DateField(auto_now_add=True)
def __str__(self):
return f"{self.user.username}-{self.task}"
Share form html
{% extends 'base.html'%}
{% load crispy_forms_tags %}
{% block content %}
<h3>Enter the Username of the Friend you want to share with</h3>
<form method="POST">
{% csrf_token %}
{{form|crispy}}
<input type="submit", value="Share">
</form>
{% endblock content %}
And the view processing it
def share(request, id):
task = Task.objects.get(id = id)
if request.method == 'POST':
share_with = User.objects.get(username = request.POST['username'])
if share_with is not None:
task.shared.add(share_with)
task.save()
return redirect('index')
else:
form = ShareForm()
return render(request, 'share.html', {'form':form})
Thanks a lot, I've been stuck for two hours, PLEASE HELP!

Django ListView dynamic context data

Given my models:
class Deck(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
class Flashcard(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
deck = models.ForeignKey(Deck, on_delete=models.CASCADE)
question = models.TextField()
answer = models.TextField()
In my html template, I want to have a table of all the user's decks, each with their number of cards, e.g. like this:
Deck1: 15
Deck2: 22
Deck3: 100
In my views I have:
def get_context_data(self,**kwargs):
context=super(generic.ListView,self).get_context_data(**kwargs)
context['number_decks']=Deck.objects.filter(owner=self.request.user).count
context['number_cards']=Flashcard.objects.filter(owner=self.request.user,deck__name="Deck1").count
number_decks works as expected.
number_cards also works when I manually type the name in.
But how can I do this without specifying the name, so that in the html template I can just say:
{% for deck in deck_list %}
<td>{{deck.name}}</td>
<td>{{number_cards}}</td>
{% endfor %}
And since I won't know the names of the decks that users will create.
I've tried deck__id=deck.id, but I get zeroes.
How can I change either my models or views to get what I want?
You could just write that as a function to your Deck-Model:
class Deck(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
def count_flashcards(self):
fc = Flashcard.objects.filter(deck=self).count()
return fc
And in your template:
{% for deck in deck_list %}
<td>{{deck.name}}</td>
<td>{{deck.count_flashcards}}</td>
{% endfor %}
You might want to use a cached attribute decorator here as well

django: How can i get multiple instances of model Userinfo when each instance of Userinfo has multiple instances in Education model

I have two models that I am working with. First one is a education model in which one user can enter multiple educational qualifications instances:
class Education(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
degree_name = models.CharField(max_length=150,null=True,blank=True)
institute_name = models.CharField(max_length=150, null=True, blank=True)
date_start = models.CharField(null=True,blank=True,max_length=25)
date_end = models.CharField(null=True,blank=True,max_length=25)
description = models.TextField(null=True,blank=True,max_length=1000)
Second Model is the 'User info' model in which one user can have maximum one instance:
class Userinfo(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
user_info = models.ForeignKey(User_info,related_name='user_info',on_delete=models.CASCADE,null=True)
profile_pic = models.FileField(null=True,blank=True)
dob = models.CharField(max_length=25,null=True,blank=True)
nationality = models.CharField(max_length=100, null=True, blank=True)
headline = models.CharField(max_length=160, null=True,blank=True)
summary = models.TextField(max_length=1000, null=True, blank=True)
current_salary = models.FloatField(null=True,blank=True)
japanese_level = models.CharField(max_length=50, null=True, blank=True)
english_level = models.CharField(max_length=50, null=True, blank=True)
career_level = models.CharField(max_length=50,null=True,blank=True)
availability = models.CharField(max_length=50, null=True, blank=True)
expected_salary = models.FloatField(null=True, blank=True)
job_role = models.CharField(max_length=50,null=True)
When I use any query to get any instance of 'User info' like:
Userinfo.objects.filter(user=request.user)
How can i related both models so that when looping through Userinfo, I should be able to get multiple instances of it in Education model. How should I change my models and query them ?
I see that you already have a foreign key to the User model inside your Education model. There is no need for a foreign key in the UserInfo Model. You can fetch all the Education instances for a given user just by making an extra call:
Education.objects.filter(user=request.user)
or you can change request.user to the actual user that you need to get.
EDIT:
without making any changes to your code, you can get the multiple instances in the following way:
example views.py
def myView(request):
user_info = Userinfo.objects.get(user=request.user) #using get since only 1 instance always
educations = Education.objects.filter(user=request.user) #fetching all the instances for the education
context_dict = {"user_info": user_info}
educations_list = []
for e in educations:
educations_list.append(e)
# do whatever you need with the educations
# you can access user_info fields just by `user_info.field_name`
# and you can access the current education fields by `e.field_name`
context_dict["educations"] = educations_list
return render(request, "template.html", context_dict)
example usage in template.html
{% if user_info %}
<p>{{ user_info.field_name }}</p>
{% if educations %}
{% for e in educations %}
<div>{{ e.field_name }}</div>
{% endfor %}
{% endif %}
{% endif %}
EDIT 2 (including multiple userinfo instances)
views.py
def myView(request):
user_infos = Userinfo.objects.filter() # fetch all instances
context_dict = {}
result = []
for u in user_infos:
temp = []
educations_list = []
educations = Education.objects.filter(user=u.user) # fetch educations for the currently iterated user from user_infos
for e in educations:
educations_list.append(e)
temp.append(u) # append the current user_info
temp.append(educations_list) # append the corresponding educations
result.append(temp)
context_dict["result"] = result
return render(request, "template.html", context)
template.html
{% if result %}
{% for r in result %}
<div>{{ r.0 }}</div> <!-- r.0 is your currently iterated user_info can be used like: r.0.profile_pic for example -->
{% if r.1 %}
{% for e in r.1 %}
<div>e.degree_name</div> <!-- e is the current education on the current user_info -->
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
the code in the views.py is not perfect and might be worth to refactor a bit (how to build the final dictionary), but i believe this will give you an idea of how to do it.
Hope this helps!
ui = Userinfo.objects.filter(user=request.user)
this query will give you all the instances of Userinfo for request.user. you can access the value of Education attributes with looping like this:
for u in ui:
ui.education.degree_name
# and so on for other fields.
I think maybe your UserInfo model can have a OneToOne relationsship with user and then do something like
UserInfo.objects.filter(user=request.user).education_set.all()
Hope this helps.
Good luck!

django - can't filter object and transfer to template

I've got a model which I'm trying to filter according to an argument passed in the url, then display the filtered object via a template, but I don't know what I'm doing wrong.
Here's the urls.py:
url(r'^courses/(?P<course_code>\w+)/$', views.course, name="course"),
Here's the view:
from website.models import Course
def course(request, course_code):
current_course = Course.objects.filter(short_title='course_code')
template = loader.get_template('website/course.html')
context = Context({
'current_course': current_course,
})
return HttpResponse(template.render(context))
Here's the model:
class Course(models.Model):
title = models.CharField(max_length=200)
short_title = models.CharField(max_length=5)
course_type = models.CharField(max_length=100)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
fee = models.IntegerField()
places = models.IntegerField()
venue = models.CharField(max_length=200)
description = models.TextField()
short_description = models.TextField()
age_low = models.IntegerField()
age_high = models.IntegerField()
And here's the template:
{% if current_course %}
{% for course in current_course %}
{{ current_course.title }}
{% endfor %}
{% else %}
<p>Sorry, that course doesn't exist.</p>
{% endif %}
And when I load the page /courses/CR1 (the course with short_title="CR1" definitely exists because it renders fine on another template where I'm not filtering but just displaying all the courses), it gives me "Sorry, that course doesn't exist."
Can anyone see what I'm doing wrong?
In this line:
current_course = Course.objects.filter(short_title='course_code')
You're checking for course titles with the exact text 'course_code'. You mean to use the value of the variable course_code:
current_course = Course.objects.filter(short_title=course_code)