I'm working on my blog page
basically the blog has category for split the same posts,
for this
I made a class for category and made a relationship between the category and my post class like this :
class Category(models.Model):
name = models.CharField(max_length=256)
def __str__(self):
return self.name
class Post(models.Model):
image = models.ImageField(upload_to='Posts_image')
title = models.CharField(max_length=256)
configure_slug = models.CharField(max_length=512)
slug = models.SlugField(max_length=512,null=True,blank=True)
content = HTMLField('Content')
date = models.DateTimeField(auto_now_add=True)
categories = models.ManyToManyField(Category)
tags = TaggableManager()
publish = models.BooleanField(default=False)
def __str__(self):
return self.title
after this I made this function
def blog_category(request):
res_posts = Post.objects.all()
category = request.POST.get('categories__name')
if category:
res_post = res_post.filter(
Q(categories__name__icontains=category)).distinct()
context = {
'posts':res_posts,
}
return render(request, 'Blog/category-result.html', context)
I tell you how its works:
when the users click on the one of category title in the blog page
this functions start work and search how many posts has this category title and list them in the category-result.html
but this function doesn't work correctly
I think this code doesn't work correctly
category = request.POST.get('categories__name')
request.Post can't take the categories__name when user click
Can you help me for this problem???
As you said the user clicks I'm assuming the category title links to a something like http://your.site/your-view?categories__name=selected-category, if that's the case what you need to use is request.GET not request.POST.
Related
I have this model
class Post(models.Model):
title = models.CharField(max_length=100)
title2 = models.CharField( max_length=100)
content = models.TextField(default=timezone.now)
content2 = models.TextField(default=timezone.now)
post_image = models.ImageField(upload_to='post_pics')
post_image2 = models.ImageField(upload_to='post2_pics')
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
Then I have this simple view function that allows me to access each of its field in my HTML:
def home(request):
postings = {
'listings' : Post.objects.all(),
}
return render(request, 'front/front.html', postings)
{% for listings in listings%}
<h1>{{listings.content}}</h1>
{% endfor %}
With this, I'm able to access the content field for every instance of that model and display it
My question is how can I access the content field in my view function and change it. The content field holds a zipcode and I want to use an API to display the city of that zipcode(which I already know how to do) and pass it back to the h1 tag. Each instance holds a unique zipcode so I need it to apply for each instance. How would I approach this?
the simplest way would be to create another variable(from views) which finds the city for a corresponding zipcode and send it through the context dictionary to the template.
OR
Add a model city setting default and Null and later based on the entered pincode you can set value to the city attribute of the model..
If you want to edit the value of the CONTENT to the city name ... then ,
The best way would be to override the save method and set the value there,
models.py :
class Post(models.Model):
...
def save(self, *args, **kwargs):
self.content = API_VALUE_OF_city_name
super(Post, self).save(*args, **kwargs)
if you want to update it from views,
in views.py :
instance_update = Post.objects.filter(id = <pk of Post>).update(content = NEWLY FOUND CITY NAME)
I am trying to display a brand of a bike in my django admin panel. I have managed to display the title, but I am struggling with the brand.
Here's my models.py:
class Bike(models.Model):
item = models.OneToOneField(Item, on_delete=models.CASCADE)
category = models.ManyToManyField(Category, blank=True)
image = models.ImageField(upload_to='bikes')
brand = models.ManyToManyField(Brand, null=True)
def __str__(self):
return self.item.title
class Brand(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
I have tried that:
def __str__(self):
return self.brand.name
But nothing is displaying then. Any ideas how to display the self.item.title and brand name at the same time?
Try this instead and see if it works.
`def brand_names(self):
return ', '.join([x.name for x in self.brand.all()])`
You need to return brand name in str
So I give you stuff apply that
def ___str__(self):
return ",".join([brand.name for brand in self.brand.objects.all()])
Above stuff give all the brand name in your admin panel
I'm very confused about this right now,
so I know when there's a simple code like the below
def text_detail(request ,course_pk, step_pk):
step = get_object_or_404(Text, course_id = course_pk, pk=step_pk)
course_pk and step_pk from the url, and those requests are set equal to course_id and pk here. but what I don't understand is what is course_id and pk here? I mean, course_id is from Course model which is foreignkey to step. so it's self.Course.id so it's course_id. But then, how about the next one pk? shouldn't it be step_id = step_pk? when it's just pk how does django know which pk it is?
Sorry if the question is very confusing, I'm very confused right now.
Edit
class Step(models.Model):
title = models.CharField(max_length=200)
description = models.CharField()
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
abstract = True
ordering = ['order',]
def __str__(self):
self.title
class Text(Step):
content = models.TextField(blank=True, default="")
Actually the get_or_404() method doing a similar/exact job as below,
try:
return Text.object.get(pk=step_pk,course_id = course_pk)
except Text.DoesNotExist:
raise Http404
You can read the source code of the same here
What is course_id and pk ?
Both are attributes of your Text model, as the name indicates pk is your Primary Key of Text model and course_id is the id/pk of course field which is a FK.
EDIT
Text is inherited from Step model so, it will show properties of usual python class.Hence, the Text model be like this internally (not-exact)
class Text(models.Model):
content = models.TextField(blank=True, default="")
title = models.CharField(max_length=200)
description = models.CharField()
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
ordering = ['order', ]
def __str__(self):
return self.title
Example
text = Text.objects.get(id=1) # text instance with id=1
text.course_id # will hold the id of "course" instance which is related to the particular "text" instance
URL assignment and all those stuffs are entirely depends on your choice and logic. So If you need to get a Text instance in your view, do as below,
text = get_object_or_404(Text, pk = pk_of_TEXT_instance)
How to create an object for a Django model with a many to many field?
From above question i come to know we can save Many to Many field later only.
models.py
class Store(models.Model):
name = models.CharField(max_length=100)
class Foo(models.Model):
file = models.FileField(upload_to='')
store = models.ManyToManyField(Store, null=True, blank=True)
views.py
new_track.file = request.FILES['file']
new_track.save()
And file uploading working fine then later i modify my code to add store then i am here...
Now i am sure db return id's here. Then i tried with my below code but that's given me error only
x = new_track.id
new = Foo.objects.filter(id=x)
new.store.id = request.POST['store']
new.save()
ok so the error here is 'QuerySet' object has no attribute 'store'
And also i tried with add that's now working either.
So the question is how to save()
the right way of saving objects with manytomany relations would be:
...
new_track.file = request.FILES['file']
new_track.save()
new_store = Store.objects.get(id=int(request.POST['store']))
new_track.store.add(new_store)
As of 2020, here's my approach to saving ManyToMany Field to a given object.
Short Answer
class HostingRequestView(View):
def post(self, request, *args, **kwargs):
form = VideoGameForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.updated_by = request.user
obj.save()
selected_categories = form.cleaned_data.get('category') #returns list of all selected categories e.g. ['Sports','Adventure']
#Now saving the ManyToManyField, can only work after saving the form
for title in selected_categories:
category_obj = Category.objects.get(title=title) #get object by title i.e I declared unique for title under Category model
obj.category.add(category_obj) #now add each category object to the saved form object
return redirect('confirmation', id=obj.pk)
Full Answer
models.py
class Category(models.Model):
title = models.CharField(max_length=100, null=True, unique=True)
class VideoGame(models.Model):
game_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=False, null=False)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=False, on_delete=models.CASCADE)
category = models.ManyToManyField(Category) #ManyToMany Category field
date_added = models.DateTimeField(auto_now_add=True, verbose_name="date added")
forms.py ModelForm
class VideoGameForm(forms.ModelForm):
CATEGORIES = (
('Detective', 'Detective'),
('Sports', 'Sports'),
('Action', 'Action'),
('Adventure', 'Adventure'),
)
category = forms.MultipleChoiceField(choices=CATEGORIES, widget=forms.SelectMultiple())
class Meta:
model = VideoGame
fields = ['name', 'category', 'date_added']
views.py on POST
class HostingRequestView(View):
def post(self, request, *args, **kwargs):
form = VideoGameForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.updated_by = request.user
obj.save()
selected_categories = form.cleaned_data.get('category') #returns list of all selected categories e.g. ['Sports','Adventure']
#Now saving the ManyToManyField, can only work after saving the form
for title in selected_categories:
category_obj = Category.objects.get(title=title) #get object by title i.e I declared unique for title under Category model
obj.category.add(category_obj) #now add each category object to the saved form object
return redirect('confirmation', id=obj.pk)
URL path for redirect
urlpatterns = [
path('confirmation/<int:id>/', Confirmation.as_view(), name='confirmation'),
]
I hope this can be helpful. Regards
new.stores.all()
returns all stores linked to the object.
Maybe:
Change Foo to Tracks
Tracks.objects.filter(id=x) to Tracks.objects.get(id=x)
Let me know how it goes
why this confusion so much.. you are getting the id there then, call the store like
new_track.save()
new_track.store.add(request.POST['store'])
I have managed (with a lot of assistance) to create a basic test blog in django 1.4.6 and python 2.7.
I can display the blog entries as a list (main page) and then allow the user to view each individual blog entry by clicking on the blog entry link.
I am now attempting to display the blog entries by author and by archive (by the published date of the blog entry).
Is it possible to have the one blog page that can list the blogs by date (most recent first), by author and by archive (by the date - most recent last)?
I am assuming the code is written in the urls.py and views.py files with the output to the single blog page, but I haven't yet found an example to work from and I can't quite figure this out on my own.
Here is my models.py:
class BlogPostDetails(models.Model, FillableModelWithLanguageVersion):
blog_post_title = models.CharField(max_length=50)
blog_post_date_published = models.DateField()
blog_post_author = models.CharField(max_length=25)
blog_post_body = models.TextField()
blog_post_allow_comments = models.BooleanField(default=False)
blog_post_timestamp_added = models.DateTimeField(auto_now_add=True, auto_now=False)
blog_post_timestamp_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.blog_post_title
class Meta:
ordering = ['-blog_post_date_published']
verbose_name = ('Blog')
verbose_name_plural = ('Blogs')
Here is my views.py:
def blog_post_item(request, blog_posts_id):
blog_posts = BlogPostDetails.objects.get(pk=blog_posts_id)
language_versions = get_language_versions(user=request.user)
return render(request, 'core/details/blog/blog_item.html', {
'blog_posts': blog_posts,
'display_default_language': display_default_language(request.user),
'languages': LANGUAGES,
'language_versions': language_versions,
'language_versions_num': len(language_versions),
})
def blog_post_list(request):
blog_posts = BlogPostDetails.objects.filter(blog_post_date_published__lt=datetime.today())
language_versions = get_language_versions(user=request.user)
return render(request, 'core/details/blog/blog_list.html', {
'blog_posts': blog_posts,
'display_default_language': display_default_language(request.user),
'languages': LANGUAGES,
'language_versions': language_versions,
'language_versions_num': len(language_versions),
})
Here is my urls.py
url(r'^details/blog/blog_list/$', 'blog_post_list', name='blog_post_list'),
url(r'^details/blog/blog_item/(?P<blog_posts_id>\d+)/$', 'blog_post_item', name='blog_post_item'),
Some advices:
You shouldn't use model name prefix in model field names, as you see code look much better:
class BlogPost(models.Model, FillableModelWithLanguageVersion):
title = models.CharField(max_length=50)
date_published = models.DateField()
author = models.CharField(max_length=25)
body = models.TextField()
allow_comments = models.BooleanField(default=False)
timestamp_added = models.DateTimeField(auto_now_add=True, auto_now=False)
timestamp_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __unicode__(self):
return self.title
class Meta:
ordering = ['-date_published']
verbose_name = ('Blog')
verbose_name_plural = ('Blogs')
Update django up to 1.6
User class-based views(filtering and ordering example)
And yes - it is posible to use one template for you task
You should pass order type as url parameter.
url(r'^details/blog/blog_list/(?P<order_type>\w+)/$', 'blog_post_list', name='blog_post_list'),
def blog_post_list(request, order_type='date_published'):
blog_posts = BlogPost.objects.filter(date_published__lt=datetime.today()).order_by(order_type)
language_versions = get_language_versions(user=request.user)
return render(request, 'core/details/blog/blog_list.html', {
'blog_posts': blog_posts,
'display_default_language': display_default_language(request.user),
'languages': LANGUAGES,
'language_versions': language_versions,
'language_versions_num': len(language_versions),
})
If you want to use one url - the only way that i see is javascript on page ordering.