How can I create a new url in a Django app? - python

I have implemented a model in a Django app and I would like add an url to handle the view for this model.
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
Can you help me?

I would recommend the Django tutorial as well: https://docs.djangoproject.com/en/1.10/intro/tutorial01/
However, to answer your question, you could do a setup like this:
views.py:
from django.shortcuts import render
from .models import Post
def my_view(request):
posts = Post.objects.all()
return render(request, 'template.html', {'posts': posts})
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.my_view, name='my_view')
]

Related

Django : HttpRequest.__init__() takes 1 positional argument but 2 were given

So I simply want when I click on the particular article to output its slug, for example if the slug of the given article is django-rules then i want it to be outputted as django-rules when i click on it. just that
here is my model
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
body = models.TextField()
date = models.DateTimeField(auto_now_add = True)
#add in tubnail and author later
def __str__(self):
return self.title
def snippet(self):
return self.body[:50]+'...'
Here is my views.py
from datetime import date
from django.shortcuts import render
from .models import Article
from django.http import HttpRequest
# Create your views here.
def article_list(request):
articles = Article.objects.all().order_by('date')
return render(request,'articles/article_list.html', {'articles': articles} )
def article_detail(request, slug):
return HttpRequest(slug)
url.py
from posixpath import relpath
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
from . import views
app_name = 'articles'
urlpatterns = [
path('', views.article_list, name = 'list'),
path('<slug:slug>/', views.article_detail, name = 'detail'),
]
Please dont suggest to add as_view()
its not working.
Instead of return HttpRequest(slug), you need to return HttpResponse(slug).

Django URL Path from DB file value

I am trying to create 'project' pages that have their paths generated with the
{{ project.title }} values, rather than the current method I have which uses ints. I don't quite understand how I can do this, but feel I am close?
Models.py
from django.db import models
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
technology = models.CharField(max_length=20)
image = models.FilePathField(path='projects/static/img/')
live = models.URLField()
source = models.URLField()
def __str__(self):
return self.title
Urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.project_index, name="projects"),
path("<int:pk>/", views.project_details, name="project_details"), # PK for Primary Key
]
Views.py
from django.shortcuts import render
from .models import Project
# Create your views here.
def project_index(request):
projects = Project.objects.all()
context = {'projects': projects}
return render(request, 'projects/project_index.html', context)
def project_details(request, pk):
project = Project.objects.get(pk=pk)
context = {'project': project}
return render(request, 'projects/project_details.html', context)
I figure path("<int:pk>/", will need to be a slug, but I just cannot figure out how to tie in the DB data.
Potentially context = {'project': project}?
Currently the url is http://127.0.0.1:8000/projects/1/ - I am looking for http://127.0.0.1:8000/projects/EXAMPLE/
Thanks
You have to add a SlugField to your models.py file:
Models.py
from django.db import models
from django.utils.text import slugify
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
technology = models.CharField(max_length=20)
image = models.FilePathField(path='projects/static/img/')
live = models.URLField()
source = models.URLField()
slug = models.SlugField(default="", blank=True, null=False, db_index=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
Views.py
from django.shortcuts import render
from .models import Project
# Create your views here.
def project_index(request):
projects = Project.objects.all()
context = {'projects': projects}
return render(request, 'projects/project_index.html', context)
def project_details(request, slug):
project = Project.objects.get(slug=slug)
context = {'project': project}
return render(request, 'projects/project_details.html', context)
Urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.project_index, name="projects"),
path("<slug:slug>/", views.project_details, name="project_details"),
]
Make sure to run makemigrations and then migrate.
urls.py
path("<title>/", views.project_details, name="project_details"),
views.py
def project_details(request, title: str):
project = Project.objects.filter(title=title).first()
if project is None:
titles = list(Project.objects.all().values_list('title', flat=True))
msg = f'Project(title=title) not found. Exist titles are: {titles}'
raise Exception(msg)
...

Django associate form values to user

I'm very new to Django but I started to create a project and I need some help. My question is very basic but I can't find the right answer.
I made a questionnaire that works fine but I don't know how to do that if a logged in user adds his answers Django associate the answers to the user.
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import loader
from .models import Stressz_teszt
from .forms import StresszForm
from django.forms import ModelForm
def stressz_item(request):
form = StresszForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('stressz/login.html')
return render(request, 'stressz/stressz-form.html', {'form':form})
Urls.py
from . import views
from django.urls import path
from django.forms import ModelForm
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login, name='login'),
#stressz teszt form
path('add', views.stressz_item, name='stressz_item'),
path('<int:item_id>/', views.detail, name='detail'),
Forms.py
from django import forms
from django.forms import ModelForm
from .models import Stressz_teszt
class StresszForm(forms.ModelForm):
class Meta:
model = Stressz_teszt
fields = ['stressz_v01', 'stressz_v02', 'stressz_v03', 'stressz_v04', 'stressz_v05',] ...
Models.py
from django.db import models
from django.contrib.auth.models import User
class Stressz_teszt(models.Model):
def __str__(self):
return self.stressz_name
user_name = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
stressz_name = models.CharField(max_length=200)
stressz_company = models.CharField(max_length=300)
stressz_v01 = models.IntegerField()
stressz_v02 = models.IntegerField()
stressz_v03 = models.IntegerField()
stressz_v04 = models.IntegerField()
stressz_v05 = models.IntegerField()
...
Thank you in advance!
You can do it like this :
def stressz_item(request):
if form.is_valid():
stressz_teszt = form.save(commit=False)
stressz_teszt.user_name = request.user
stressz_teszt.save()
return redirect('stressz/login.html')
return render(request, 'stressz/stressz-form.html', {'form': form})

Django class based view: passing additional information to the next view

I'm very new to Django and a bit overwhelmed by the documentation. I think my problem is pretty simple but everything i've found just confused me more.
I am building a little news app with a model NewsItem:
from django.db import models
from django.utils import timezone
# Create your models here.
class NewsItem(models.Model):
title = models.CharField(max_length=50)
newsText = models.TextField()
dateEntered = models.DateTimeField('date entered')
datePublished = models.DateTimeField('date published', blank=True, null=True)
user = models.CharField(max_length=30) #temporary field. will be changed to user foreign key
def __str__(self):
return self.title
def publish(self):
if (self.datePublished == None):
self.datePublished = timezone.now()
def published(self):
return self.datePublished != None
two views (technically 3) index and detail
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views import generic
from .models import NewsItem
# Create your views here.
class IndexView(generic.ListView):
template_name = 'news/index.html'
context_object_name = 'latestNewsList'
def get_queryset(self):
return NewsItem.objects.order_by('-datePublished')[:5]
#todo
class DetailView(generic.DetailView):
model = NewsItem
template_name = 'news/detail.html'
def publish(request, itemId):
newsItem = get_object_or_404(NewsItem, pk=itemId)
newsItem.publish()
newsItem.save()
return HttpResponseRedirect(reverse('news:detail', args=(newsItem.id,)))
and an urlconf like this
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:itemId>/publish', views.publish, name='publish'),
]
In the detail view i have a link Publish which just triggers the function views.publish. This view is supposed to redirect back to the detail view.
What i'm trying to do now is to display a little message (like article successfully published) in detail view when it was redirected by the publish view. But i have no idea what would be a good aproach
I could just render the details template in the publish view, but then it would still say news/publish in the URL instead of news/detail
Thanks in advance for your help
Have a look at the messages framework. You could add a success message before redirecting, which will be displayed on the next page.
from django.shortcuts import redirect
from django.contrib import messages
def publish(request, itemId):
newsItem = get_object_or_404(NewsItem, pk=itemId)
newsItem.publish()
newsItem.save()
messages.success(request, "The post has been published")
return redirect('news:detail', newsItem.id)
Note that I've simplified the return statement to use redirect(...) instead of HttpResponseRedirect(reverse(...)).

Slug URL not working in Django

I am trying to setup Slug urls in a Django project. I keep getting a 404 error and can not find what I am missing. I have done this several times before but for some reason I must missing something.
models.py
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
# Create your models here.
class Pages(models.Model):
title = models.CharField(max_length=250, default="Add Title Here")
content = models.TextField(default="Add Content Here")
slug = models.SlugField(unique=True)
seo_title = models.CharField(max_length=250, default="Add Title Here")
seo_description = models.CharField(max_length=160, default="Add Seo Description")
active = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, null=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True, null=True)
def __unicode__(self):
return self.title
class Meta:
unique_together = ('slug', 'title')
def get_absolute_url(self):
return reverse("single_page", kwargs={"slug": self.slug})
views.py
from django.shortcuts import render, get_object_or_404, Http404
# Create your views here.
from .models import Pages
def Single(request, slug):
try:
page = get_object_or_404(Pages, slug=slug)
context = {'page': page}
template = 'pages/page_detail.html'
return render(request, template, context)
except:
raise Http404
urls.py
from django.conf.urls import url, patterns
from . import views
urlpatterns = [
url(r'^(?P<slug>[\w-]+)/$', views.Single, name='single_page'),
]
Thanks guys for your help. I found the issue with some help from #vastlysuperiorma
Views.py
def single(request, slug):
try:
page = get_object_or_404(Pages, slug=slug)
context = {'page': page}
template = 'pages/page_detail.html'
return render(request, template, context)
except Pages.DoesNotExist:
raise Http404

Categories

Resources