I'm running Django 1.2.1 for my personal website with a blog. It's all fine and dandy, but I've found that all the browsers I've tried (Firefox, Chromium, Opera) are caching webpages, which of course is a problem for other users viewing my blog (being that it won't load new posts up unless they empty their cache or force refresh the page). I didn't have this problem when my site ran on PHP, so how would I go about fixing this seemingly Django-related problem?
I've only been working with Django for about a week or so, so I don't really know where abouts I should be looking to fix something like this. Thanks in advance!
The way I do each page (and each blog post) is as a Page/Post object respectively so I can use the admin interface without having to write my own. Although the issue is happening for both situations, I'll just give the Post class for now:
class Post(models.Model):
author = models.ForeignKey(User, default=User.objects.get(username='nathan'))
status = models.ForeignKey(Status, default=Status.objects.get(text='Draft'))
date = models.DateTimeField(default=datetime.datetime.now())
title = models.CharField(max_length=100)
post = models.TextField()
categories = models.ManyToManyField(Category)
def __unicode__(self):
return u'%s' % self.title
def link(self):
return u'/blog/post/%s' % self.title
class Meta:
ordering = ['-date']
And here's my urls.py:
from django.conf.urls.defaults import *
from django.views.generic import list_detail
from feeds import PostFeed
from models import Post
blog_posts = {
'queryset': Post.objects.filter(status__text__exact='Published'),
}
urlpatterns = patterns('getoffmalawn.blog.views',
(r'^$', list_detail.object_list, blog_posts),
(r'^archive/(\d{4})$', 'archive'),
(r'^rss/$', PostFeed()),
(r'^search/$', 'search'),
(r'^tag/(.+)/$', 'tag'),
(r'^post/(.+)/$', 'post'),
)
If you guys would like to see the code from views.py, just ask and I'll throw that up too.
Edit:
Here's the views.
view.py for the blog App:
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, redirect
from django.core.context_processors import csrf
from django.db.models import Q
from models import Post, Category
def post(request, title):
post = Post.objects.get(title=title)
c = locals()
c.update(csrf(request))
return render_to_response('blog/post_detail.html', c)
def blog_detail(request, blog_id):
post = get_object_or_404(Post, pk=blog_id)
return list_detail.object_detail(request, queryset=Post.objects.all(), object_id=blog_id)
def archive(request, month, year):
pass
def search(request):
if request.method == 'GET':
query = request.GET['q']
object_list = Post.objects.filter(Q(post__icontains=query) | Q(title__icontains=query), status__text__exact='Published')
return render_to_response('blog/post_list_sparse.html', locals())
def tag(request, tag):
object_list = Post.objects.filter(categories__text__exact=tag, status__text__exact='Published')
return render_to_response('blog/post_list.html', locals())
The problem was that it really was browser-based caching, as I was told by a member on the Django-users mailing list. The reason I didn't see this problem in PHP is that it was sending cache suppression headers.
The solution was to add the #never_cache decorator to the relevant views.
Here is the documentation for caching in django.
https://docs.djangoproject.com/en/1.2/topics/cache/
Not ideal, but you can make all of the pages tell the browsers not to cache anything, to see if that helps.
https://docs.djangoproject.com/en/1.2/topics/cache/#controlling-cache-using-other-headers
Related
I am using slug to to show my blog details page.
here is models.py
class Blog(models.Model):
author=models.ForeignKey(User,on_delete=models.CASCADE,related_name='post_author')
blog_title=models.CharField(max_length=264,verbose_name='Put a Title')
slug= models.SlugField(max_length=264,unique=True)
blog_content=models.TextField(verbose_name='what is on your mind?')
blog_image=models.ImageField(upload_to='blog_images',verbose_name='Image')
publish_date=models.DateTimeField(auto_now_add=True)
update_date=models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-publish_date',)
def __str__(self):
return self.blog_title+' From :'+str(self.author)
blog list views.py
def Creating_blog(request):
form=BlogForm()
if User.is_authenticated:
if request.method=='POST':
form=BlogForm(request.POST,request.FILES)
blog_obj=form.save(commit=False)
blog_obj.author=request.user
title=blog_obj.blog_title
blog_obj.slug = title.replace(' ','-') + '-'+ str(uuid.uuid4())
blog_obj.save()
return redirect('bloglist')
return render(request,'blogs/createblog.html',{'form':form})
blog details views.py
def blog_details(request, slug):
if User.is_authenticated:
blog= Blog.objects.get(slug=slug)
already_liked=Likes.objects.filter(blog=blog,user=request.user)
if already_liked:
like=True
else:
like=False
comments=Comment.objects.filter(blog=blog)
commet_form=CommentForm()
if request.method=='POST':
commet_form=CommentForm(request.POST)
if commet_form.is_valid():
comment=commet_form.save(commit=False)
comment.user=request.user
comment.blog=blog
comment.save()
return HttpResponseRedirect(reverse('blog_details',kwargs={'slug':slug}))
return render(request,'blogs/blogdetails.html',context={'blog':blog,'comment_form':commet_form,'comments':comments,'like':like})
else:
HttpResponseRedirect(reverse('login'))
urls.py
from django.urls import path
from .import views
urlpatterns = [
path('write/',views.Creating_blog,name='creatingblogs'),
path('bloglist/',views.BlogList.as_view(),name='bloglist'),
path('details/<slug:slug>/',views.blog_details,name="blog_details")
]
blog_list page html anchor tag code
<div class="col-sm-8">
<p>{{blog.blog_content|capfirst|truncatewords:100}}Read More</p>
</div>
I can see the blog list page but when it try to see blog details it shows me this error
DoesNotExist at /details/big-time-space-rarity-9a3d63b4-634a-11ec-9db9-9c7bef6a0e62/
Blog matching query does not exist.
I have tried adding some new blog but it shows me the same. please help me out this and kindly ask me if any description needed. Thanks in advance.
The error occurs inside the blog_details view in the row:
blog= Blog.objects.get(slug=slug)
You should debug this part of the code and determine why you can't find the Blog instance by slug.
It's quite a wild guess as I'm not reproducing your code but in my opinion something with your slug seems wrong.
First change the following line:
blog_obj.slug = slugify(title + '-' + str(uuid.uuid4()))
see: https://docs.djangoproject.com/en/4.0/ref/utils/#django.utils.text.slugify
then change the following:
<p>{{blog.blog_content|capfirst|truncatewords:100}}Read More</p>
(remove slugify in the template)
Let me know if this worked. Also, if you need help with class based views, just let us know.
I have a simple site project in Django and I have movies lists in man page and movies details in the second page.
I want to add a delete button on movies details tab where user can delete the movies object.
views.py
def movies_list(request):
return render(request, 'movies.html',{'movies':movies.objects.all()})
def movies_details(request,slug):
movies_details=MyModel.objects.all()
det=get_object_or_404(movies_details, slug_name=slug)
return render(request, 'movies_details.html',{'movies_details':movies_details,'det':det})
what is the better method to do that ?
something like this using new view :
def delete(request, id):
note = get_object_or_404(Note, pk=id).delete()
return HttpResponseRedirect(reverse('movies_details.views.movies_details'))
urls.py
url(r'^delete/(?P<id>\d+)/$','project.app.views.delete'),
or some like this ?
if request.POST.get('delete'):
obj.delete()
or use some Django form ?
You can use DeleteView functionality of django. I think that will be the better one.
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
class DeleteTaskView(DeleteView):
template_name = 'template/delete.html'
model = Task
pk_url_kwarg = 'id'
def get_success_url(self):
return reverse_lazy('movies_details.views.movies_details')
For example I have a url in my urls.py-
url(r'^my-url/$', views.my_view)
Now on a particular action from views, I want to remove this url from urlpatterns and add a new url during runtime. Is it possible, if so, how?
Changing url handler during runtime is not best practice instead you could have the checkpoint in db and handle all the incoming request
models.py
class Version(models.Model):
version_number = models.IntegerField()
is_latest = models.BooleanField(default=False)
urls.py
url(r'^handler/(?P<version>\d+)/$', views.handler)
views.py
from django.shortcuts import get_object_or_404
def handler(request, version):
obj = get_object_or_404(Version, version_number=4)
if obj.is_latest:
return render(request,'base.html')
else:
return render(request, 'old.html')
Above code authorise only version 4 ( /handler/4 )
I am trying to create a restful api using class based views in django.
class SomeAPI(MultiDetailView):
def get(self,request,format=None):
#some logic
def post(self,request,format=None):
#some logic
I want to process a get request like www.pathtowebsite.com/api?var1=<someval>&var2=<someval>&var3=<someval>
My post url would be www.pathtowebsite.com/api/unique_token=<token_id>
Basically a get request would generate a unique token based on some parameters and a post request would post using that token.
How would my URL file look like in such a scenario?
P.S I have hardly ever worked with class based views.
First of all: DRF will do a lot of your legwork for you, even generate consistent URLs across your API. If you want to learn how to do things like this in the Django URL dispatcher then you can embed regexes in your URLS:
project/urls.py:
from django.conf.urls import url
from project.app.views import SprocketView
urlpatterns = [
url(r'^api/obj_name/(P<id>[a-f0-9]{24})/$', SprocketView.as_view()),
url(r'^api/obj_name/unique_token=(P<id>[a-f0-9]{24})/$', SprocketView.as_view()),
]
project/app/views.py
from django.shortcuts import get_object_or_404
from django.views.generic import View
from .forms import SprocketForm
from .models import Sprocket
class SprocketView(View):
def get(request, id):
object = get_object_or_404(Sprocket, pk=id)
return render(request, "sprocket.html", {'object':object}
def post(request, id):
object = Sprocket.get_or_create(pk=id)
object = SprocketForm(request.POST, initial=object).save(commit=False)
object.user = request.user
object.save()
return render(request, "sprocket.html", {'object':object, 'saved':True})
That's a lof of functionality that frameworks are supposed to lift from you and I suggest reading about Django CBV. One resource I can wholeheartedly recommend is Two Scoops.
I am doing a Django project and when I tried to access 127.0.0.1:8000/articles/create, I got the following error in my Ubuntu terminal:
/home/(my name)/django_test/article/forms.py:4: RemovedInDjango18Warning: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is deprecated - form ArticleForm needs updating
class ArticleForm(forms.ModelForm):
In addition, I also got the following error when visiting my actual localhost site:
ValueError at /articles/create/
The view article.views.create didn't return an HttpResponse object. It returned None instead.
Here is my forms.py file:
from django import forms
from models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
And here is my views.py file:
from django.shortcuts import render_to_response
from article.models import Article
from django.http import HttpResponse
from forms import ArticleForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
#import pdb; pdb.set_trace()
# Create your views here.
def articles(request):
language = 'en-us'
session_language = 'en-us'
if 'lang' in request.COOKIES:
language = request.COOKIES['lang']
if 'lang' in request.session:
session_language = request.session['lang']
return render_to_response('articles.html',
{'articles':
Article.objects.all(), 'language' : language,
'session_language' : session_language})
def article(request, article_id=1):
return render_to_response('article.html', {'article':
Article.objects.get(id=article_id) })
def language(request, language='en-us'):
response = HttpResponse("setting language to %s" %
language)
response.set_cookie('lang', language)
response.session['lang'] = language
return response
def create(request):
if request.POST:
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/articles/all')
else:
form = ArticleForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('create_article.html', args)
I'm not sure how to fix this problem. I looked at the Django documentation but I couldn't find a solution to my problem so any help would be appreciated.
For your form, it's a warning, not an error, telling you that in django 1.8, you will need to change your form to
from django import forms
from models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = '__all__' # Or a list of the fields that you want to include in your form
Or add an exclude to list fields to exclude instead
Which wasn't required up till 1.8
https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#selecting-the-fields-to-use
As for the error with your views, your return is inside of an if statement: if request.POST: so when it receives a get request, nothing is returned.
def create(request):
if request.POST:
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/articles/all')
else:
form = ArticleForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('create_article.html', args)
Just dedent the else block so that it's applying to the correct if statement.
You just need...
from django import forms
from models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
exclude = ()
...to fix your form. You'll need to post your view code to see what's up with that.
if you use fields = __all__ as Ngenator suggested, and if it's a project that might have to run under various versions of Django, the following conditional will be needed:
if django.VERSION >= (1, 6):
fields = '__all__' # eliminate RemovedInDjango18Warning
otherwise you get the error django.core.exceptions.FieldError: Unknown field(s) (a, l, _) specified for CrispyTestModel, as seen here: https://travis-ci.org/maraujop/django-crispy-forms/jobs/56996180
In your view, you don't return anything if the request is not a POST. You should move everything from the else statement onwards back one indent.