Django Photologue Upload Photo Example - django

I've installed Django-Photologue and I can upload files and create galleries in my Django admin site. I've been searching the documentation below for examples on how to create a photo upload form so my users can create a gallery on my site but can't find a simple example to get me started. I've also setup their example application but it wasn't very helpful in terms of how to upload and create Galleries by POSTing from Views/Templates.
Docs:
https://django-photologue.readthedocs.org/en/2.7/
https://code.google.com/p/django-photologue/
Can someone please provide a simple example of how I can create an upload form for submitting photos and creating a gallery for use with Django-Photologue ( not using just admin site)?

This is quite simple, Photologue has all the relevant logic inside its models.
For example to setup photo upload, you can use CBV:
urls.py
from django.views.generic import CreateView
from photologue.models import Photo
urlpatterns = patterns('',
url(r'^photologue/photo/add/$', CreateView.as_view(model=Photo),
name='add-photo'),
(r'^photologue/', include('photologue.urls')),
...
In your template, remember to set enctype attribute, to handle files.
templates/photologue/photo_form.html
<form action="" method="post" accept-charset="utf-8" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Submit">
</form>
That's basically all you need.. as you can see, we don't use any custom logic, everything is encapsulated inside Photo model and the CBV does the rest.
The same applies to Gallery, just replace the model with Gallery and you're good to go.
Obviously if you need some customization, you can do it as well, but that's outside the scope, since you didn't specify what use case you need to handle.

One thing missing from the answer above is you have to set the success_url in the CreateView.as_view. For example: CreateView.as_view(model=Photo, success_url='/')
Otherwise you'll receive a ImproperlyConfigured error.

Related

Django & AJAX to show DB objects upon user's input submission

I'm pretty new in the Web development world, have been using Django so far.
I've been trying to figure out how to render data back to page after clicking on a submit button, so I see I'll need to use AJAX for that purpose.
I've created a very simple app just to understand the basics of AJAX.
However, googling, I couldn't really find a basic straight-forward implementation so I kinda got lost...
What I'm trying to achieve:
I have a model called Country:
class Country(models.Model):
name = models.CharField(primary_key=True, max_length=35)
continent = models.CharField(max_length=10)
capital = models.CharField(max_length=35)
currency = models.CharField(max_length=10)
And a super simple main page that asks the user to insert some country name.
The idea is to bring to the page all the info from the DB.
So it would look like this:
Main page HTML body:
<body>
<h2><em>Please type a country name:</em></h2><br><br>
<div class="container">
<form id="get_info" method="post">
{{ form }}
{% csrf_token %}
<input id="submit_button" type="submit" name="submit" value="Get info">
</form>
</div>
</body>
views.py:
from django.shortcuts import render
from country_trivia import forms
def main_page(request):
get_info_form = forms.GetInfo()
return render(request, 'country_trivia/index.html', {'form': get_info_form})
forms.py:
from django import forms
class GetInfo(forms.Form):
country_name = forms.CharField(label="")
I've seen some examples using forms, but I'm not even sure if it's needed, as I've seen some other examples that count on 'onclick' even listeners, then "grab" the text in the search field and pass it via AJAX...
How should I build my AJAX object for that simple purpose, and how should I integrate it?
Do I need to use forms at all?
I don't post anything to DB, just query it and print out data...
Thanks!!

How can i add a "like" button in a Django class ListView

I am pulling my hair out trying to add a "like" button in my siteĀ“s post app, but as i want to add it in a ListView that contains the rest of the posts entries and everyone has the option to be commented I have added a Formixin to do so, so, now i cannot add another form for the like button as it would mean two posts requests....so I am not finding a clear solution... I have read here and there about using AJAX or Json techs but as im new programing im kind of stuck in it... has anyone any tip to offer?
While using AJAX (javascript XHR requests) would be the proper way so the page doesn't need to be refreshed when just clicking a like button, you can do it without AJAX.
HTML
On the HTML side of things, you can have multiple forms (<form>), one for each post, which have a hidden input field that's the post's id. You have set that explicitly in the HTML template, e.g.
{% for post in post_list %}
<h3>{{ post.title }}</h3>
<p>{{ post.summary }}</p>
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ post.id }}" name="{{ form.id.html_name }}">
<input type="submit">Like</input>
</form>
{% endfor %}
So basically you're reusing the form multiple times, changing the "value" attribute to match the post.
Django Form
Adding the FormMixin to your view is the right step, just use the form_class to a custom LikeForm with just one field that's an IntegerField called id.
View
By adding the FormMixin you get the form_valid() method, which you'll want to override to save the like:
def form_valid(self, form):
id = form.cleaned_data['id']
try:
post = Post.objects.get(id=id)
except Post.DoesNotExist:
raise Http404
post.likes.add(self.request.user) # assuming likes is a m2m relation to user
return redirect('post_list') # this list view
Hopefully I am not so late, I had similar challenges trying to implement the same functionalities on my website.
I came to realize that each button id should be unique (Preferably the post id if blog), but the classes can be the same.
I was able to solve it. Here is an article I wrote on medium recently on the steps I followed to so get this working you can check it out here

How to correctly render multiple apps on the main page

So I'm currently learning to use Django, and I'm wondering how to correctly split up parts of the functionality while still displaying it on the main page.
For example, I want the header + navigation, a calendar and recent blog articles on the main index page.
On the view article page I'd for example have the header + nav, the calendar and a single article with a comment section.
Now reading the tutorials, if I understand them correctly, I'd split the functionality in a header app, a calendar app and the blog app itself while glueing it together with a core app.
But what I don't understand is how to render apps/other views in the main app. All the ways I found only specify templates itself or look very hacky, so apparently that doesn't seem to be the common way to go.
So there are multiple views are work here:
1.The views that you want to show
2.The view that will render the page, displaying all of the views (lets call this the 'main view'.
The first step is to import all of the other views / models into the views.py file that the main view resides in.
from blog.models import Post
from calendar.models import Calendar
Now you can edit your mainview to acces this data. For example:
class Mainview(TemplateView):
template_name = 'app/homepage.html'
def get_context_data(self, **kwargs):
#This will only show the latest post
data['posts'] = Post.objects.all().order_by('-id')[:1]
data['calendar'] = Calendar.objects.all()
return data
Now you can acces the data from the other apps in your template using the {{ }} tags, for example - you could do something like this:
{% for post object in post %}
{{ post.title }}
{{ post.content}}
{% endfor %}

Restricting Access to Django's success_url()

New Django user here.
I am trying to restrict access to Django's success_url() upon GET requests. I realize I am not the first to ask this question, however, I am specifically trying to achieve this in conjunction with Django's generic class-based views. Generic views seem cleaner, faster, and more idiomatic. I want to use them as much as possible unless they are absolutely unfit for the job.
Basically, I am creating a simple contact form for non-users who only want to send me a message without creating an account. I've created a contact app to handle these types of contacts. I've created a ModelForm, which I am rendering with a contact.html with Django's FormView. After a person submits the form, they will receive a cool looking thank you message, rendered with a thanks.html, which has its own url.
But I only want them to see the thank you message if they POST the contact form. Currently, you can go on my site and type '/contact/thanks/', and my thanks.html will be rendered whether you've submitted a form or not. Django's success_url apparently defaults to a GET request.
Here's my view:
class MyContact(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = 'thanks'
Here's my form:
ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['email_address', 'message_body']
Here's the html form in contact.html:
<form action="" method="POST">{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="send btn btn-secondary">Send Message</button>
</form>
My first thought was to decorate my contact app url with a require_POST() decorator like this:
urlpatterns = [
url(r'^thanks/$', require_POST(views.ThanksPageView.as_view()), name='thanks'),
]
This doesn't work because Django's success_url() defaults to a GET request.
What is the most idiomatic way to approach this? Since Django is a 'batteries included' framework, I do not want to use 'duck-tape', meaning I do not want implement any ad-hoc logic in my views or urls.
Sorry if I've missed anything in the docs or questions archive.
Since you're asking for a idiomatic approach, I would consider the messages framework and specifically the SuccessMessageMixin. This would allow you to add a success message to e.g. the contact form itself and the url-pattern for the /thanks/ page would not be necessary.

How do I load an image, which was uploaded earlier ,onto a HTML file?

So I set up profile pic upload as guided by http://www.tangowithdjango.com/book/chapters/login.html.
Then I found the second answer(by user Raisins) to useful for my purpose and implemented it Extending the User model with custom fields in Django. As I've been that this answer is outdated, I've also tried the solution offered here for migration Get rid of get_profile() in a migration to Django 1.6 which hasn't improved my situation
Then in my views, I add required details including the image to a dictionary, and render i to the HTML page. It looks as though the UserProfile isn't returning the right object.
u=User.object.get(username__exact=request.user)
profile=UserProfile.objects.get(user=u)
global client
client['login']=True
client['name']=u.username
client['password']=u.password
client['email']=u.email
client['picture']=profile.picture
return render(request,'index.html',{'client':client})
And when I try to display the details on HTML page, everything except image is loaded.
I tried
<img src="profile_images/{{client.picture}}">
where profile_images is in the root directory. I inspected the element and I find this
<img src="/static/profile_images/%7B%7B%20client.picture%20%7D%7D">
where I was expecting "1.jpg" instead of "%7B%7B%20client.picture%20%7D%7D".
Any help is appreciated. Thanks
Raisin's answer is outdated. Please don't use AUTH_PROFILE_MODULE in Django 1.6 anymore. In fact, you don't even need to handle the post_save signal.
Based on the same tutorial, you will find the code for your view:
u = User.objects.get(username=request.user)
try:
p = UserProfile.objects.get(user=u)
except:
p = None
return render(request,'index.html',{'client':client, 'userprofile':p})
In your template use:
{% if userprofile.picture %}
<img src="{{ userprofile.picture.url }}" />
{% endif %}
I solved my problem by using
{% load staticfiles %}
<img src="{% static client.picture %}" />