How to put the page title in a url pattern with Django? - django

If I wanted to send the blogpost id to the url pattern, and have the url automatically turn into something like www.blog.com/post/2/this-is-my-second-blogpost, how might I do that?
Inside of urls.py I have a url pattern that accepts the blogpost id, and its title. It doesn't seem to be working, and once it does, would be tedious to add the title for every page in this manner.
urls.py:path('post/<int:post_id>/<str:post_title>', views.view_post, name='view_post'),
blogposts.html template:
Read More
views.py: def view_post(request, post_id, post_title):.

Simply, add the default argument of post_title to be None. If you are wishing to get the post_title directly from the post_id, neclect the post_title, doing this won't give you error as functions already got all the satisfied argument values.
So:
def view_post(request, post_id, post_title=None):
Edit
Okay, what user wanted was about slug field. Slug field is the field type in django model. Basically, it is used for the url type. In above problem, what pyknight202 wanted was the url patter for the post_title. So, you could not use tilte directly as url as they contain spaces, so for that you have to add post_title in hyphens or underscore to be readable. Therefore, you need slug field in Post model.
https://helloworld.com/1/this-is-example
So, 1 is post_id as slug could not be unique, so you could not only retrieve from post_title therefore you need post_id too. Refs

Maybe you should use a slug field for the url instead of the combination of id and title, your url will look like example.org/title-to-object-2/.
Now you have a unique slug field with the title and the id.

Related

Wagtail - made custom slug but page not serving from it

I made a custom slug because the default slug does not meet my needs and already set the url_path with the new slug. But the page is still serving with the default slug.
I've already set the url_path with the following code:
def set_url_path(self, parent):
super().set_url_path(self)
if parent:
self.url_path = parent.url_path + self.custom_slug + '/'
return self.url_path
But when I publish the page, it still returns the page with the default slug value. I thought Wagtail serves the page on url_path. What other methods or variables do I have to override for the page to be served on my custom slug?
You can not switch to some other field then slug. The slug field is used all over Wagtail to lookup url's, queries and serve the correct page.
You can programatically set the slug value to something else. The Page.slug definition is:
slug = models.SlugField(
verbose_name=_('slug'),
allow_unicode=True,
max_length=255,
help_text=_("The name of the page as it will appear in URLs e.g
http://example.com/blog/[my-slug]/")
)
The field accepts unicode chars.
You should override Page._get_autogenerated_slug, Page.full_clean and Page.clean. Change how slug is handled and adopt to your wishes.
Note you can use some other field eg my_custom_slug as an input and use this value in your custom methods. Eg: self.my_custom_slug. However, the final result has to be stored in the slug field.
You can remove the slug field from the content panels to remove it from the admin user interface.
Finally, the slug has to comply with https://www.rfc-editor.org/rfc/rfc1738

Django Rest Framework Url Field Serializer

I have a model named File which contains a field named 'url'.
class File(models.Model):
"""
Generic File model
"""
filename = models.CharField(max_length=500)
url = models.URLField()
Now if I pass this URL :
https://s3.us-east-2.amazonaws.com/xyz/2018-09-25_17:39:16.80 (1).pdf
Note the space in the url before (1). The model serializer gives an error stating that the url is invalid.
Do I need to encode the url myself by replacing the space with '%20'
First of all, generate files without whitespaces if possible. That would be a better solution.
If it's not possible, change the URLField() to CharField(), which will compromise the URL Validation. But, it's possible to use as a valid url.
If you still want to use URLField(), write a custom validator and add it via validator parameter
def custom_url_validator(value):
# your validation
class File(models.Model):
"""
Generic File model
"""
filename = models.CharField(max_length=500)
url = models.URLField(validators=[custom_url_validator,])

django - dynamic query on form field

Lets say I have a form with some fields. I was wondering if it is possible to do dynamic query where I could do a string match while the user is typing into a field. Like when typing into google it returns a list of choices when you type into the search bar. Can someone give me an example on how and where to implement it?
If what you're looking to achieve is fields for a ForeignKey then you can provide a Queryset on the form field then use an app like django_select2 which can then provide a widget which will allow a user to search for items in the Queryset for the field. e.g.
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=u"City",
widget=ModelSelect2Widget(
model=City,
search_fields=['name__icontains'],
dependent_fields={'country': 'country'},
max_results=500,
)
)
Then in the form, as you started to type into the city field it'd start to search on City.name using an icontains lookup. The docs for this are here.
If that's not what you're looking for then you could just write some Javascript which detected input to a field, then sent an ajax request to a view with the contents of your field. That could then return a response which displayed content in the page related to the input.

Difference between using url tag and get_absolute_url

If I have a model like this:
class Article(models.Model):
title = models.CharField(max_length=200)
# ... rest of the code ...
def get_absolute_url(self):
return reverse('article-detail', args=[str(self.pk)])
and I have an url mapping like this:
url(r'^article/(?P<pk>[0-9]+)/$', views.ArticleView.as_view(), name='article-detail'),
In template should I use:
{{ article.title }}
or
{{ article.title }}
I'm still thinking both are good ideas, but which is the best?
In the first code I've written args=[str(self.pk)], why I must convert self.pk into string? URLs must be strings?
In my generic view, how do I use pk variable?
I'm really confused with that slug_field, slug_url_kwarg, pk_url_kwarg, query_pk_and_slug.
Which matches which?
If I set query_pk_and_slug to True, slug_field = pk?
In my opinion,use
{{ article.title }}
is better practice.
If later on you want to change the url of this resource, you will do it once in your models function, and you would not search every template page for reference to this specific url.
The philosophy behind this, is that the url for an article is a resource that belongs to the model of the article (django: Fat models and skinny controllers?)
A better approach, is to write
return reverse('article-detail', kwargs={'pk': self.pk})
This way, and when having multiple args in your url, you know every time the value of each arg (*args and **kwargs?)
I am not sure about the last part of your question. All in all, pk represents the primary key, which by default (and leave it as it) is the id (automatically produced by your database), and slug is a unique field in database (you specify it in your model definition) that represents a SlugField. Slug is used when you prefer more readable (seo) urls like /article/giannis-antetokounmpo-is-the-best, instead of /article/404.
For understanding how the class-based views work in django (better practice than function-based) take a look https://ccbv.co.uk/projects/Django/1.10/django.views.generic.detail/DetailView/ for example.
When the GET (http method is called), the get function of the model is called as a result. If you notice, there is a self.get_object() function. In the definition of the get_object(), you can see the logic you are searching for. Specifically, in the comments, you can see all the ways, that View is trying to find the one and only object to return. You must choose one, by specifying the appropriate variables.
url tag will do the reverse operation and generate a url path, where as get_absolute_url should be defined in a model as this is to get url for a particular object.
Here is a post explaining get_absolute_url

How would you populate a field based on another field

From the admin panel I want to populate a slug field based on a certain text field
eg.
Title: My Awesome Page
would automaticaly populate
Slug: my_awesome_page
There used to be a prepoulate_from option for the SlugField up to 0.96. It became an admin option after that. See here for reference on that.
Alternatively, you could override the model's save method to calculate the value of the slug field on save().
This question may be helpful, too.
There is also an app called django-autoslug which provides a field type AutoSlugField. Using that, you could have:
class Something(models.Model):
title = models.CharField(max_lenght=200)
slug = AutoSlugField(populate_from='title')
...
This AutoSlugField has many nice features, such as generating a slug so that it is unique either globally of combined with some other field (maybe a category or the year part of a DateTimeField).
See http://pypi.python.org/pypi/django-autoslug for further details.