I'm new to django and I really have no idea how should I structure a website for the purpose of posting articles (like tutorials).
I'm not asking for specific code, but how does it work?
Should I make a base template and a html file for every single article that I'll post? If so, how should be the folder structure in the project? How can I show a list of all those articles and redirect to them if a user clicks on it? Should I link them to a database entry? How can I do that?
I'm asking those things because I only did things that involved reading content from the database/model and showing it on a template, but articles need images and other special construction that a blog textfield would not be enough.
If it is too confusing, just say so, and I'll try to put in another words, I'm really struggling to put my question into words.
I think you are just starting with Django, and if that is correct, I suggest you to start by making a hello world app to have a quick grasp of how django works, here is a good tutorial.
If you aren't just skip that part and start by writing down the requirements.
If you want your blog articles to have a header image, or a special text field in which you can write rich text, or even if you want to build a categories/tag system, write that in your requirements.
For each thing you would like to have django has already some ways to solve it.
For example for the image of the article you will use a django model field name ImageField.
I'll give you a really basic reference for the article model (You'll have to start a project and create an app).
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=140)
body = models.TextField()
image = models.ImageField(upload_to="blog/images")
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Remember to make use of views and template language, but if you need some help with the image in the template just use this:
{% if post.image %}
<img src="{{ post.image.url }}" title="Post image">
{% endif %}
Also you have to realize that you'll need a hosting service like heroku or amazon for your app, and a media CDN to host the images of your posts. If you decide to use heroku i recommend to use Cloudinary and here is a tutorial.
If you need some inspiration feel free to checkout my blog.
Related
Well I know that what I'm doing is not very feasible, but I wanted to know if there's any way to do this.I want to create a portfolio blog to post some 3d renders, for that I want to have more control over the structure of the page. for this I created two models (one for the post and another to receive the images, linking them to the post through a foreign key) so that I could have an indefinite number of images, the problem came when I decided that I wanted to be able to choose the one positioning of the images according to my need/desire, for that I did the following:
I used django summernote temporarily to be able to test the written posts, I knew that it would probably not be possible to do this because the content sent from the models is static.
I have the following models:
class Post(models.Model):
titulo_post=models.CharField(max_length=255, verbose_name='Titulo')
autor_post=models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name='autor')
data_post=models.DateTimeField(default=timezone.now, verbose_name='Data publicação')
conteudo_post =models.TextField()
publicado_post=models.BooleanField(default=False, verbose_name='Status publicação')
def __str__(self) :
return self.titulo_post
and:
class Estudo(models.Model):
imagem=models.ImageField(upload_to='estd_img/%Y/%m/%d', blank=True, null=True)
post=models.ForeignKey(Post, on_delete=models.CASCADE)
I tried to put the following value in the field "conteudo_post" through the administrative area to see if it would work
<div class="container">
<div class="col-10 mx-auto">
<img class="img-fluid " src="{{imagem.0.url}}" alt="">
</div>
</div>
as I thought it didn't work, when I use {{post_conteudo}} the rendered html displays an escaped version of the content, when I use {{post_conteudo |safe}} it creates the image container, but is not able to find it. when checking the browser's developer mode I can see that the value of {{image.0.url}} was not processed and it remains in that format in the final html
I am new to django before this only made 1 project and that was just a follow along video so obviously the fix is probably very easy, but I am trying to make a restaurant reservation page, and later on there will be user authentication to only show the reservation that particular user made, but right now I want to display all of the reservations in my modal and trying to learn how to actually display the data.
here's the modal:
https://gyazo.com/066e3e060492990008d608a012f588f3
here's the view: https://gyazo.com/6947ed97d84b38f1e73680e28f3a0a9a
Here's the template: https://gyazo.com/966c4810b3c7f4dd8dad2e5b71c2179c
I am spent about 3 hours watching other videos on people loading there modal data in there website and when they do it I understand everything but for some reason I can't apply that to my own project, my guess is my for loop is wrong since I have a hard time with writing them and seem to always mess up, so any help so I can at least start looking in the right direction would be appreciated
When using class based views you'll have to work with django conventions. For example where you have reservations = Reservation.objects.all(), reservations is not a defined class attribute for the class based view. What you can do is rename it to queryset instead.
from django.views.generic import ListView
class ReservationList(ListView):
model = Reservation
queryset = Reservation.objects.all()
context_object_name = 'reservations' # using this attribute to alias the queryset
template_name = "make_a_reservation.html"
This way you can now use the name reservations in your template as you did with:
{% for i in reservations %}
...
{% endfor %}
That should work.
after I saved one item using MyModelClass.save() method of django in one view/page , at another view I use MyModelClass.objects.all() to list all items in MyModelClass but the newly added one always is missing at the new page. i am using django 1.1
i am using mysql
middleware setting
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.locale.LocaleMiddleware',
)
my model:
class Company(models.Model):
name = models.CharField(max_length=500)
description = models.CharField(max_length=500,null=True)
addcompany view
def addcompany(request):
if request.POST:
form = AddCompanyForm(request.POST)
if form.is_valid():
companyname = form.cleaned_data['companyname']
c = Company(name=companyname,description='description')
c.save()
return HttpResponseRedirect('/admins/')
else:
form = AddCompanyForm()
return render_to_response('user/addcompany.html',{'form':form},context_instance=RequestContext(request))
after this page
in another view
i called this form in another view
class CompanyForm(forms.Form):
companies=((0,' '),)
for o in CcicCompany.objects.all():
x=o.id,o.name
companies+=(x,)
company = forms.ChoiceField(choices=companies,label='Company Name')
to list all companies but the recently added one is missing.
The transaction should be successful, since after i do a apache server reboot , i can see the newly added company name
Thanks for any help...
The issue is that you're (once, at import-time) to dynamically building a choices list in your form declaration, but expecting it to be modified each time you use the form. Python doesn't work that way.
See here for docs on choices:
http://docs.djangoproject.com/en/dev/ref/models/fields/#choices
But in particular, this bit:
"[I]f you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever."
Similar applies to forms. Perhaps you want a ModelForm and ModelChoiceField?
As pointed out by other users, the choices are created at the time that you import your module (only once) so they're not going to get updated after the first use.
You should most likely use the django.forms.ModelChoiceField to accomplish this. It takes a queryset and allows you to customize the label as well.
Another way you could do this is to wrap your code in a function, and return a new class each time. That's really not as nice of an approach since the framework provides you with ModelChoiceField, but it's an option since python allows you to return locally defined classes.
Your CcicCompany.objects.all() code is only run once when the Form class is first parsed. So of course any additional objects will not be in this list. You can achieve this in the form's __init__ method instead, so it is run afresh each time a form is generated. You can access the choices via self.fields['field_name'].choices
I'm guessing you're doing something similar to the following:
m = MyModelClass(foo='bar')
m.save()
or
MyModelClass(foo='bar').save()
or
kwargs = {'foo':'bar'}
MyModelClass(**kwargs).save()
Perhaps sharing some code might provide more insight.
Well, I hoped that you would post more code (as I mentioned in my comment), so I'm still guessing...
Are you using TransactionMiddleware and is it possible that the first request does a rollback instead of a commit?
Which database backend are you using? (if it is Sqlite, then consider using PostgreSQL or MySQL, because sqlite does not play nice with regard to concurrent connections)
Please post all relevant code (full class including possible managers in your models.py, as well as the full views), maybe then it's easier for others to help you.
UPDATE:
Your code:
companies=((0,' '),)
for o in Company.objects.all():
x=o.id,o.name
companies+=(x,)
is quite unusual, and it's still not clear what you put into the template. The code is a bit unusual since you are creating a tuple of tuples, but I can't see an error here. The bug must be somewhere else.
Anyway, I'd rather do something like that instead of creating tuples:
view:
companies = Company.objects.all()
return direct_to_template(.... {'companies': companies...} ...)
template:
{% for company in companies %}
<!-- put an empty company at the top of the list for whatever reason -->
{% if forloop.first %}
whatever<br />
{% endif %}
{{ company.name }}<br />
{% endfor %}
OK, so let me give you an overview first. I have this site and in it there is a form section. When you access that section you can view or start a new project. Each project has 3-5 different forms.
My problem is that I don't want viewers to have to go through all 3-5 pages to see the relevant information they need. Instead I want to give each project a main page where all the essential data entered into the forms is shown as non-editable data. I hope this makes sense.
So I need to find a way to access all that data from the different forms for each project and to feed that data into the new page I'll be calling "Main". Each project will have a separate main page for itself.
I'm pretty much clueless as to how I should do this, so any help at all would be appreciated.
Thanks
You could try this. After that, you could:
Try creating a model for each project. This is done in "models.py" of the application modules created by django-admin
Use views to show that data to people (on your Main page)
If you've already seen all that, then:
First, you should create a view for your main page. So if you have an application my_app, my_app/views.py should be like:
def main_page_view(request, project_name):
# Your code here
pass
Then, to use this, you'd modify urls.py and add in something like:
(r'^projects/(?:<project_name>[a-zA-Z0-9]+)', 'my_app.views.main_page_view'),
Also, you'd need models, which are created in models.py, by subclassing django.models.Model
EDIT: re-reading your question, I guess you need this
Data can be passed from a view to a template through the context.
So say you create a summary view...
def summary(request, *args, **kwargs):
In that view you can query the database using the model api and pass the result of that query into the template for rendering. I'm not sure what your models look like, but say you had a model that had a title and the owner (as a ForeignKey to user)...
class Project(models.Model):
title = models.CharField(max_length=250)
user = models.ForeignKey(User)
Your model will be obviously be different. In your view you could query for all of the models that belong to the current user...
def summary(request, *args, **kwargs):
projects = Project.objects.filter(user=request.user)
Once you've gathered that, you can pass in the query to the template rendering system...
def summary(request, *args, **kwargs):
projects = Project.objects.filter(user=request.user)
render_to_response('project_summary.html', {'projects': projects }, ... )
When you pass the query to the template, you've named it projects. From within the template you can access it by this name...
<body>
<table>
{% for project in projects %}
<tr><td>{{ project.title }}</td></tr>
{% endfor %}
</table>
</body>
(Notice also how you can access a property of the model from within the template as well.)
I'm writing a simple real-estate listing app in Django. Each property needs to have a variable number of images. Images need to have an editable order. And I need to make the admin user-proof.
So that said, what are my options?
Is there a ImageList field that I don't know about?
Is there an app like django.contrib.comments that does the job for me?
If I have to write it myself, how would I go about making the admin-side decent? I'm imagining something a lot slicker than what ImageField provides, with some drag'n'drop for re-ordering. But I'm a complete clutz at writing admin pages =(
Variable lists, also known as a many-to-one relationship, are usually handled by making a separate model for the many and, in that model, using a ForeignKey to the "one".
There isn't an app like this in django.contrib, but there are several external projects you can use, e.g. django-photologue which even has some support for viewing the images in the admin.
The admin site can't be made "user proof", it should only be used by trusted users. Given this, the way to make your admin site decent would be to define a ModelAdmin for your property and then inline the photos (inline documentation).
So, to give you some quick drafts, everything would look something like this:
# models.py
class Property(models.Model):
address = models.TextField()
...
class PropertyImage(models.Model):
property = models.ForeignKey(Property, related_name='images')
image = models.ImageField()
and:
# admin.py
class PropertyImageInline(admin.TabularInline):
model = PropertyImage
extra = 3
class PropertyAdmin(admin.ModelAdmin):
inlines = [ PropertyImageInline, ]
admin.site.register(Property, PropertyAdmin)
The reason for using the related_name argument on the ForeignKey is so your queries will be more readable, e.g. in this case you can do something like this in your view:
property = Property.objects.get(pk=1)
image_list = property.images.all()
EDIT: forgot to mention, you can then implement drag-and-drop ordering in the admin using Simon Willison's snippet Orderable inlines using drag and drop with jQuery UI
Write an Image model that has a ForeignKey to your Property model. Quite probably, you'll have some other fields that belong to the image and not to the Property.
I'm currently making the same thing and I faced the same issue.
After I researched for a while, I decided to use django-imaging. It has a nice Ajax feature, images can be uploaded on the same page as the model Insert page, and can be editable. However, it is lacking support for non-JPEG extension.
There is a package named django-galleryfield. I think it will meet your demand.