django url parameter has space,How to solve it? - django

I'm a newbie for program and study django now. I have one question.
example:
my product title: classic photo frame
my url: url(r'^(.+)/$', products, name='products'),
I open through url with www.xxx.com/classic photo frame/
it works,but the this url has space, I know it's not correct.
I add - to parameter,such as classic-photo-frame. It works too.
But this way, - will show in front-end page.
How can I resolve?
url shows /classic-photo-frame but the front-end page is classic photo frame
Thank you.

the best way use SlugField .
For more information check this link. https://docs.djangoproject.com/en/1.10/ref/models/fields/#slugfield
and you can add this line prepopulated_fields = {'slug': ('title',), } to your custom django admin class for auto generate slug in admin.
after this you can use slug in your urls

Related

How to execute code from database in Django

I created a blog with Django and my model post is like this:
class Post(models.Model):
title = models.CharField(max_length=255, unique=True, db_index=True)
content = RichTextField()
# ...
In my template, I display the content of posts like this: {{ post.content|safe }}
What I want is to execute code that is in the content of the post. Let say I want to add a link to the "about me" page, so logically I would add this in the content of the post:
# some text here
about me
# another text here
This doesn't work. if I hover the URL I can see the URL 127.0.0.1:8000/post/21/{% url 'about' %}.
How can I do that.
Edit
Actually, to redirect to the about me page I can simply do about me
But what if I want to redirect to another post? I have to specify the id or the slug of the post but I can't do:
post
"|safe" filter renders only html code.
To render django template from db you should use render or render_to_string in your view. But note that this is an extremely insecure practice cause to many contexts are available to get and execute in django template language

CreateView not uploading image and name of the user for a post

I'm making a web app which allows users to register to the site and let them post their posts.
For taking in their post I have used the built in CBV: CreateView. In the user post I take in the name of the user using foreignkey with null=True, image, title.
The problem is: when I go to the detail page of that post it shows that there is no file associated with the image field, so I made an if statement to check if the post contains an image. But then too, it does not show the image. It shows User:None.
I don't know what is happening, I have read that CBV take the self.request automatically and there is no need to link the current user to the post.
Following are the screenshots of my code:
models.py
browser image before clicking submit button
browser image after clicking submit button (detail page of the post)
post_detail.html
views.py
If the image is in you database than you can render it this way
<img src="{{post_detail.image.url}}">
I found the answer.
I forgot to add the enctype="multipart/form-data" in the form of my createview html.
Now it's working perfectly fine.
Screenshot of userpost_form.html
Thank you all for all the support.

Using Django for a very simple website: is it worth it?

Hello everyone how is it going?
I've just started using Django recently, and I've started getting my head around it; I need to build a website about cars, with two major APPS:
CarsCatalogue;
News Section;
I find the fact that I can manage the news from the admin panel extremely useful. I have created the typical model:
class Post(models.Model):
title = models.CharField(max_length = 140)
date = models.DateTimeField()
body = models.TextField()
def __str__(self):
return self.title
With the urls.py as follows
url(r'^(?P<pk>\d+)$', DetailView.as_view(
model = Post,
template_name="news/post.html"))
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:25],
template_name="news/news.html")),
This is great! I can manage the News app Extremely easyly from the admin panel. Now I have a page for each news: news/1; news/2 etc etc;
But when i go down to the CarsCatalogue, and I would really need to simplify my life because I have plenty of cars with a personal page each to add, I am instead finding myself needing to modify the urls.py for each car I need to add, and it seems I have to modify the views.py for each car -I am using render- am I right?
I mean, does it make sense to have a Views.py with one hundred different functions calling one hundred pages?
And then if I want to create a list with all the urls of the CarCatalogue, having to write every link one by one?
Is this the way to use Django in this case?
I would create another "news-style" APP for CarsCatalogue, that would be so much more easy for me to manage through the Admin Panel, but I need each url to show the car name, like: CarsCatalogue/Seat-Ibiza and not like CarsCatalogue/1.
Maybe I can do something like the news APP, but changing the way urls are generated and shown?
I am asking you all of this after I read the documentation and several Google topics and other resources;
I hope you guys will be able to clear the fog around my head;
With all the Respect such a community deserves,
Sincerely,
-oKi
EDIT n*1
It's been 3 hours of reading, trying, modifying, erasing, trying again.
I read a lot of stuff, but at the same time I got pheraps even more confused, because I found so many things while looking for how to "slug"ify the urls (that is indeed what I was looking for [now I can indeed use the admin panel to do what I wanted!] thanks) that I ended up mixing a lot of stuff. So, using the NEWS application, what I have done so far:
python3.5 manage.py flush, makemigrations, migrate, createsuperuser
I modified the news/models.py, so that it now looks like this:
from django.db import models
from django.template.defaultfilters import slugify
class Post(models.Model):
title = models.CharField(max_length = 140)
date = models.DateTimeField()
body = models.TextField()
slug = models.SlugField(title, max_length=100, unique=True)
def __str__(self):
return self.title
def slug(self):
return slugify(self.title)
I modified the news/admin.py, so that it now looks like this:
from django.contrib import admin
from news.models import Post
admin.site.register(Post)
class NewsAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": (Post.slug)} <!-- that seems makes sense looking at the Model - I also tryed {"slug": (title,)}, {"slug": (Post.title)}-->
I modified the news/urls.py, so that it now looks like this:
from django.conf.urls import url
from django.views.generic import ListView, DetailView
from news.models import Post
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:25],
template_name="news/news.html")),
url(r'^(?P<slug>[\w-]+)$', DetailView.as_view(
model = Post,
template_name="news/post.html")),
]
then I give:
python3.5 manage.py runserver
and it runs with no problem.
So I go to /admin, I create a new post, it creates it...
But then what happens?
It still uses the old "paradigm" to generate the url, including the old keys(id's) it was using before I erased the client... so... what I expected to be something like mysite/news/new-human-level-urld-news
turns out to be mysite/news/11.
LOL :D and, luckily, the browser gives me also an error...
"FieldError at /news/11
Cannot resolve keyword 'slug' into field. Choices are: body, date, id, title"
at the moment I can't find an answer, I find so much stuff that I just don't know how to mix things up. I will keep searching. Help is appreciated! Thanks for now!!! :D
According to my understanding to your problem, what you need is not to create a view function for every car you have.
Indeed, you need to create 1 template (html page) that describes your CarsCatalogue, where all the CarsCatalogues have the same structure with different information. Then the user chooses one CarsCatalogue, let's say from a dropdown control and then you load the data from your database and show your results in the template.
In order to achieve this, have a look on the following topics:
Django forms. And in order to get your data from the database, you need the the id for example to be passed in the url, you can see this answer how to pass an id in django url or from the official website URL Dispatcher.
In few words, django is a simple way to do your website and definitely no need to rewrite your code several times.
NO THERE IS NO NEED TO CREATE MULTIPLE URLS.
From what I understood, you want a catalogue for each car.
Just create a view from where you display the names of all your cars.
Then when you click on a car, make a get request to another view function in the get request pass your selected car details. Now comes the use on Django Templates. Create a Django template for your catalogue, pass the car specific data to it.
You need to read about Django Templates , I think Django templates is something that will solve your problem.
I think the thing you're missing is that the parameter in the URL can be anything, not just a numeric URL. If it's a string, we call that a slug, and the Django admin will automatically create a slug from the fields in your model if you set the prepopulated_fields option.
Then, you can use that slug in the URL:
url(r'^(?P<slug>[\w-]+)$', DetailView.as_view(
model = Car,
template_name="news/car.html"))
and Django will use that field instead of the ID to find the right content to display.
I found a way to fix my problem.
Even though I started off by asking about the CARS Catalogue, I will explain what I did using the NEWS APP instead, as the logic is the same and as that is the APP I have modified in the first EDIT of my post.
Inside the Templates, have a "news.html" page to render the list of all the Post, and a "post.html" to render every single Post.
The following is part of the procedure on how to set an APP that you can manage directly from the ADMIN PANEL, and that uses the SLUG field as URL.
models.py:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length = 140)
body = models.TextField()
slug = models.SlugField(unique=True)
def __str__(self):
return self.title
admin.py:
from django.contrib import admin
from news.models import Post
class PostAdmin(admin.ModelAdmin):
model = Post
prepopulated_fields = {'slug': ('title',)}
admin.site.register(Post, PostAdmin)
urls.py:
from django.conf.urls import url
from django.views.generic import ListView, DetailView
from news.models import Post
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all(),
template_name="news/news.html")),
url(r'^(?P<slug>[\w-]+)$', DetailView.as_view(
queryset=Post.objects.all(),
model = Post,
template_name="news/post.html")),
]
I hope that can be useful to somebody.
Jeez you gotta study hard to use this Framework :D
Thanks everybody for the support, c ya :)

In the Django admin, is there a way to show a list of actual links to a model's one-to-many objects?

If this is too complicated or not the right way to do things, feel free to link me to something else or just tell me I should do it another way...
Basically, I'm working on a project where there are Clients, and each one has an arbitrary number of Websites attached to it. So the Websites model has a ForeignKey to the Client model. The Website admin page is pretty in-depth, and each Client might have 10 or more sites, so I'd rather not have them all display as inlines, because that's really messy and crazy looking.
What I'd like is that when you go to the admin panel and click Clients, you're brought to the change page where it has the basic stuff you'd edit for the client and then an inline of actual links to each of the client's website admin pages. Like this:
Change client
General
Name:
Address:
Phone:
Websites
Link to edit Website 1
Link to edit Website 2
Link to edit Website 3
Link to edit Website 4
Link to edit Website 5
You can use a TabularInline that includes only a link to the model change page:
class ClientAdmin(admin.ModelAdmin):
# everything as normal
inlines = WebsiteInline,
class WebsiteInline(admin.TabularInline):
model = Website
fields = 'link',
readonly_fields = 'link',
def link(self, instance):
url = reverse("admin:myapp_website_change", args = (instance.id,))
return mark_safe("<a href='%s'>%s</a>" % (url, unicode(instance)))
admin.site.register(Client, ClientAdmin)
admin.site.register(Website)
See my recent question How do I add a link from the Django admin page of one object to the admin page of a related object? which was about how to do exactly this, but with several pairs of models rather than just one.

Admin, two links to different views?

in django admin the views that show the register's just have
a link to "edit", but what happen if a need an extra(S) links to
another views?
for example:
i have view that show the list of registered People, the nick is
linking to the Edit page (the normal way of Django), but i need
another links that will show me the "articles" of the people and
another the "comments" of the people.
how ill make this with django admin?
Thanks
(I'm assuming some field names from your models to answer)
Make the author field from "comment" searchable:
class CommentAdmin(admin.ModelAdmin):
search_fields = ("=author",)
Use list_display and HTML to control what's displayed on the people's list admin page:
def comments(obj):
return ('comments' % obj.name)
comments.short_description = 'comments'
comments.allow_tags = True
class PeopleAdmin(admin.ModelAdmin):
list_display = ("name", comments,)
And change /admin/pathto/comments/ to whatever your comment's admin list page is.
Basically you're going to direct your users to the comments search result page.