It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm very new to Django and am trying to build my first good app. I've decided to try to rebuild a website of low complexity, and chose: http://trailertrack.me/
I was wondering if you could tell me which steps to take.
Right now, my views.py file looks like this (I'm only trying to show one specific video at the moment):
from django.http import HttpResponse
from django.shortcuts import render_to_response
import gdata.youtube
import gdata.youtube.service
yt_service = gdata.youtube.service.YouTubeService()
yt_service.ssl = True
def index(request):
message = "Welcome, and enjoy the show!"
context = {
'message': message,
}
return render_to_response('index.html', context)
def video(request):
t = loader.get_template('index.html')
specificentry = yt_service.GetYouTubeVideoEntry(video_id='1g4PLj0PlOM')
return HttpResponse(t.render(specificentry))
Thanks for your advice!
Okay, here's a broad outline of how I'd go about doing this. The order doesn't matter too much; there's obviously some dependencies among them, but do them in the order that you feel like tackling them.
Also, if you're new to this, I'd strongly recommend using either git or, if you're already familiar with it, mercurial for version control, and virtualenv for tracking dependencies.
Get your current views working, so that you can see that one specific video with a reasonable-looking template and so on.
Add a way to show more than that one video. One straightforward way to do this is to create a simple Django model for videos, with basically just a youtube ID, and turn on the admin site so you can add videos manually.
Make the view show a random video on each load.
Add a "next" button that just reloads the page. You can either use a django session variable / GET variable to avoid showing the same video again, or just assume it won't happen often enough to be a problem if you have a lot of videos.
Add a way to get new videos from Youtube (semi-)automatically. One way to do this:
Add an "is published" field to your video model, and have the user-facing site only show published videos.
Make a management command that does a Youtube search for "trailer" or something and adds new videos (unpublished) to the database. (Check for duplicate IDs at the very least.) Run that automatically in cron every few hours or days or whatever.
Go into the admin periodically and add new videos. If you want, you can make a custom admin view that shows a bunch of pending videos on a page, with their metadata, the actual video so you can watch it, and any other videos that might be duplicates in the system, along with AJAX publish and delete buttons. (The duplicates thing is a little harder! You can probably just do tf-idf weighting on the metadata to find similar videos.
Add a way for users to log in (the default Django users system, Facebook/Twitter integration, whatever) and like/upvote/maybe downvote videos. Remember these. Add video recommendations with some form of collaborative filtering.
You now have more features than the original site! Think of some other cool ones and implement them too. :)
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Thanks in advance! This is more a "philosophical" question then a direct request for opinions on code, though I would greatly appreciate anyone's input on code examples to look at.
I've been a "traditional" developer for as long as I can remember, and now I work professionally as a data scientist. That being said, the one frontier I've never truly touched is web development.
For a project I'm working on, I need to build (and in a somewhat expedited timeframe) a good-looking web application that functions somewhat similarly to a Wiki website (using existing codebases like Mediawiki is not an option here, so assume everything has to be built from the ground-up).
In trying to do things the "right way", I've set things up as follows:
Django models are built that seem to correctly capture the relational structure of data for the webapp, at least as tested by playing with Django's admin portal
Django is hooked up to a Postgres database
(1) and (2) are running inside Docker containers
The most important piece here left, obviously, is the frontend. I've tried to ask several friends and acquaintances for advice, and have been pointed in the Bootstrap direction.
From here, I admit, I'm a bit stuck.
I see examples on the Django docs that don't involve any Javascript (it seems, with minimal lift, HTML pages can directly interact with the database, using what seems like a pretty simple "insert-placeholder-here" logic, as I have set it up through the Django models). I see a similar construction here and here.
But then I see a whole other set of instruction on the web about how to make a functional webapp-- creating serializers for the Django models to JSON, building a REST api, writing the frontend page logic using Javascript and using a library imported into Javascript to interact with the manually-built API(s) to interact with the backend.
Now, of course, the "first" approach seems much simpler. The second feels like reinventing the wheel-- if I can simply use a construction like {{ num_books }}, why would I go about building all those APIs and worrying about JSON? But I feel confused. Is there a "right" choice, thinking long-term? It seems like I can find people using Bootstrap and other frameworks taking both approaches. Can I not use Javascript code unless I take the JSON/API approach? Does that even matter? What truly are the differences here?
A compass on the rough seas would be much appreciated. Surely I cannot be the first to try to build a functional webapp with Django... the frontend is totally foreign to me.
Thank you all!
In the first place, Django is a framework which means that it contains already a predefined set of necessary functionality that most people need, sometimes people say "with batteries included".
Before REST architecture was invented front-end and back-end were closely related to each other. There wasn't a straight line between them and it was hard to share business logic with other services.
Basically we can say that there are two options, how to organize front-end and back-end workflow with Django:
Using Django templates:
The most simple and easiest way to get started. All that you need already presented in Django. Let's take a look at this simple example:
views.py
def index(request):
fruits = Fruit.objects.all()
render(request, 'index.html', {'fruits': fruits})
And after that you can use variables from the context in your template like so:
index.html
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
Django template system is really powerful and customizable if the default template engine doesn't suit your needs there is a possibility to choose another one, for example Jinja.
You can do a lot of stuff there, but as a general recommendation, all the "computing" stuff shouldn't be stored on the template level because it can dramatically increase the time rendering of the page. The better place to put business logic is views and most of the work with the database on custom managers.
For dynamic parts of your application, you could use AJAX probably from JQuery library.
It's also quite simple to work with forms, Django by default handle it with csrf protection. Default validators and model forms give you real power.
When you use templates you depend on them, most likely you couldn't reuse your endpoints somewhere else and that's why you need REST. Django has a little set of features that can help you with it and most likely you would end up with django-rest-framework usage which one of the most popular libraries used with Django today.
Using REST architecture:
The example above would look like this, though there is ModelViewSet, which do the most of boilerplate stuff for you:
class FruitViewSet(viewsets.ViewSet):
def list(self, request, *args, **kwargs):
fruits = Fruit.objects.all()
ser = FruitSerializer(fruits, many=True)
if not ser.is_valid():
return Response({}, status=status.HTTP_400_BAD_REQUEST)
return Response(ser.data, status=status.HTTP_200_OK)
You can use ModelSerializer or write your own serializers. The validation process is simple and straightforward:
class FruitSerializer(serializers.ModelSerializer):
def validate(self, attrs):
# validate your data here
pass
class Meta:
model = Fruit
fields = '__all__'
To display this data on a web page you could use whatever you want, vanilla javascript or any javascript framework which supports REST, the most popular today: React, Angular, Vue.
With REST you could use the same API for your web, mobile application and so on. In the end, implement once use everywhere.
As soon as you want to have dynamic parts in your frontend, you will need Javascript at some point. To fasten up development I highly suggest to use a framework like Vue, React or Angular. They have dozens of tools to use for particular needs within your project. Also you might look into jQuery when using Javascript.
I am currently building a Django web application myself (started like 3 months ago). I use Javascript a lot to manipulate the Django rendered templates.
Why Django might be your right choice
The nice part about Django is the Model-View-Template architecture which by my opinion is an excellent framework for your wiki app. You request a http, Django fires the linked view-function and renderes the template - et voila!. And if you need data transmission from/to PostgreSQL you just build a model and include the data calls into the view-function to use the data on the frontend.
You won't have to build a user management system (built-in
django-admin)
You will have a lot of frontend required business logic included in the Django orbit
No need to worry about JSON. You just fetch the data from the database using python objects and work with that data in the frontend. If at some point json would be a better choice for whatever reason, you just manipulate it with a Python serializer.
It is pretty easy to deploy/publish a Django based application using e.g. digitalocean.com or heroku.com
Since this was some broad question, I hope I could provide you some hints on how to proceed with your development. However, feel free to comment this post for further questions.
To give you a brief feeling I will attach some snippets of my current project, using basic HTML, CSS and Javascript along with Django as the python based backend.
I've recently started tampering with Mezzanine and I am trying to add 2 new fields to the Blog Post admin -- keywords, and meta title.
I did it by editing my admin.py file and adding the following:
from mezzanine.blog.admin import BlogPostAdmin
from mezzanine.generic.models import Keyword, AssignedKeyword
BlogPostAdmin.fieldsets[0][1]["fields"].extend(["keywords"])
BlogPostAdmin.fieldsets[0][1]["fields"].extend(["_meta_title"])
admin.site.register(Keyword)
admin.site.register(AssignedKeyword)
I see the fields in the blog post manager, but when I edit them specific to a blog post, they don't save to that post. However, if I am adding keywords, the keywords get saved to the overall site keywords (generic_keyword table).
Is there any way to make them also update the blog post such that _meta_title and keywords_string gets updated in blog_blogpost? Thanks for any help.
EDIT: After looking into this further, it doesn't seem that I need to do anything to get the "Meta Data" section to be expandable. However, in my copy, it cannot be expanded. Is there any particular reason for this?
The answer above is a bit incomplete, and will be misleading for anyone who comes across the same problem.
My guess is that at some point you copied the admin's base_site.html template into your project, from an older version of Mezzanine. You've then later upgraded to a newer version of Mezzanine, which refers to an upgraded version of chosen - you can see the commit from 3 months ago here where that occurred here: https://github.com/stephenmcd/mezzanine/commit/f4e33282eaac44ef8ebbadb9b0157d910c67973a
If anyone experiences this issue, check your javascript console. In my case, for whatever reason, the Admin section was trying to load mezzanine/chosen/chosen-0.9.12.jquery.js which doesn't exist. I edited blog/templates/admin/base_site.html and updated it to mezzanine/chosen/chosen.jquery.js and the Meta Data section became expandable/collapsible again.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
My Django site is an ecommerce store. Relatively nontechnical copy editors will be logging into the Django admin interface and writing the copy for each of the product pages. They have told me that they want to be able to create links in this copy to other pages on the site. For example, if a product references another product in its description, they want to link between the pages.
I see a couple of possible options:
They simply hardcode the urls in <a> tags in the copy. I've set up ckeditor for the admin textareas so this would be the simplest solution, but if the url structure of the site ever changed, (say we changed them for SEO purposes) all the links would break.
Introduce some sort of wiki syntax where they surround the text that they want the links to be in square brackets. Something like:
Widget A works really well with [[Widget B]]. It is good.
would produce:
Widget A works really well with Widget B. It is good.
Then you have the problem of what happens if the product's name changes?
Has anyone dealt with this problem before and come up with a solution that is flexible enough to allow changing links/names/etc?
I deal with this issue frequently. Ultimately, you have to be very persuasive to convince me to allow embedding links directly into the copy--especially with an e-commerce website.
What if the product name changes or is re-branded?
What if the product is discontinued... you don't want 404 errors from your internal links.
Do you really want to lead people away from your "add to cart" call to action that high up on the page?
Do they know your SEO strategy? Are they going to dilute your links? What verbiage will they use? Will they ensure the link is valid?
When I am asked to give copy/product development team the ability to add links I always start with a No. Ask them what they need them for, explain the problems that can arise (eg. extra cost in maintaining valid links, conversion rate considerations, SEO considerations), and offer alternative solutions.
For example, I usually offer the ability to allow them to associate products with products as "Associated Products", "Related Products", "Accessories", "More Information" etc. You can have these in tabs or lists at the bottom of the product page. These would be in models and thus you have control over not displaying discontinued products, the link names are the product names (which you have SEO control over), etc. Determine if they are going for cross-selling, up-selling, or providing the end user with more information.
As a last resort I have also used a custom code parser which is again based on the target object and not a hard-coded link. For example, let's say you give them the ability to do:
Widget A works really well with [product=123].
A custom template tag, parser in your model/view can replace that with a link to the the Product with id=123 (or use slug) based on get_absolute_url(). If the product is discontinued, the name can still show but no link. This only works if you have a policy of never deleting records. Even then, you may have to have some error handling for when they enter an invalid product ID or somebody does delete that product. That will happen.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I would like to have reusable ratings (typical layout with 5 stars).
I have found this http://www.thebroth.com/blog/119/css-rating-stars that explains how to display this using css.
For actually collecting the rating I was thinking of using an image map or maybe simple radio buttons.
I would like to use this on various different models.
How would you do this?
Shall I create a widget or can I do this with a template?
Actually I was pretty surprised not to find anything on this on the web. Is it that simple, or uncommon?
If received some interesting answers on the django-users mailing list:
by Mike:
Well you can create a widget, I like a seperate rating model myself. That
collects the value and then adds that to a total and creates a score or
average. The model stores the total votes and the total score, which I divide
and get my average, (I do the math in the view). Adding it to other models
with a foreign key relation. Enforcing that users vote only once is rarely
enforced outside of the current session or cookie lifetime. If you want it
persistance, I'm notfgv6gw33TT sure off the top of my head what is best for
this, but would require only registered users vote.
Now, you just display the rating form, I would do it as a template inclusion
tag and put the tag in my templates. This tag has the basic submit form, the
form it's self is two fields, with a select box (I went simple this way) and a
hidden field labeled next that points back to this page, that I can redirect
to. When the user submits, in my views to handle the forms action, I just
increment the votes and total score and redirect back to the page the vote was
taken on. This is using the traditional submit button, posting the form to a
url, returning a full view.
If you do something with javascript that illuminates the number of stars for
the rating and click on the stars to submit, here you might want to post it as
json object using xhr request, update the view and return a json object with
the updated rating values, if it's a 200, update the page with the new values
after voting (returned with the 200). If it's a 500, deal with the error,
letting the user know, there was a problem voting and reset the stars.
This is what I do, or would do in your position, if anyone has a better idea,
please speak up.
Hope this helps.
Mike
by Ethan:
I actually just did 5-star ratings for a project I'm working on, and have
been trying to figure out if I have anything reusable worth releasing as a
package (and trying to find the time to figure that out..) I'll outline
what I did and what I used to do it.
I used django-ratings[1,2] for the backend and hooked up its RatingField to
my rateable models.
I like jQuery, so for the frontend I used the jquery-star-rating plugin[3,4]
as a base. It turns a collection of radio buttons into a star widget. I
haven't looked closely at the implementation but I think it's basically
using the same CSS technique described in your link. To get started you
just need to include its JS and CSS and add class="star" to the radio
buttons in your form.
I then just wrote some view code that sends the request data from the radio
buttons to django-ratings. Super simple stuff, just used the django-ratings
RatingManager API and handled the exceptions it throws -- I've pasted the
snippet from my code at [5]. (I'm using a somewhat old version of
django-ratings b/c I haven't had the time to upgrade; it might look a little
different now, I'm not sure.)
Finally, I wanted two more things:
1) If a user has already rated an item and views the "rate this item" form
again, the "star widget" should be preset with the user's previous rating,
instead of just showing five blank stars. I realized the easiest way to do
this was from the client side: an onload event that simulates the user
clicking on the star he already clicked on. My view and template code for
that is at [6]; I just figured out the HTML formats that jquery-star-rating
sets and expects, and clicked on the appropriate star for the user's
existing rating.
2) When viewing the item, users' ratings should show up as non-interactive
stars, instead of as numbers. I wrote a dumb-as-nails template filter
designed to take a number (the rating) and return a bunch of star images.
Again, I just used the HTML formatting and CSS classes from
jquery-star-rating. My code for this is at [7].
I was thinking it'd be neat to put some of this in a django-form Field that
renders the radio buttons and triggers jquery-star-rating all in one go, and
handles the submission to the django-ratings backend. But I haven't had a
chance to figure that out yet.
Anyway, hope this helps,
Ethan
1 http://github.com/dcramer/django-ratings
[2] http://pypi.python.org/pypi/django-ratings
[3] http://www.fyneworks.com/jquery/star-rating/
[4] http://code.google.com/p/jquery-star-rating-plugin/
[5] http://pastebin.ca/1650596
[6] http://pastebin.ca/1650609
[7] http://pastebin.ca/1650616
There is a django-ratings app on PyPi. It can give you the rating as a percent 'myinstance.rating.get_percent()' to use in your template for the inner div width in the CSS trick you mentioned.
I'm going to be honest: this is a question I asked on the Django-Users mailinglist last week. Since I didn't get any replies there yet, I'm reposting it on Stack Overflow in the hope that it gets more attention here.
I want to create an app that makes it easy to do user friendly,
multiple / mass file upload in your own apps. With user friendly I
mean upload like Gmail, Flickr, ... where the user can select multiple
files at once in the browse file dialog. The files are then uploaded
sequentially or in parallel and a nice overview of the selected files
is shown on the page with a progress bar next to them. A 'Cancel'
upload button is also a possible option.
All that niceness is usually solved by using a Flash object. Complete
solutions are out there for the client side, like: SWFUpload
http://swfupload.org/ , FancyUpload http://digitarald.de/project/fancyupload/
, YUI 2 Uploader http://developer.yahoo.com/yui/uploader/ and probably
many more.
Ofcourse the trick is getting those solutions integrated in your
project. Especially in a framework like Django, double so if you want
it to be reusable.
So, I have a few ideas, but I'm neither an expert on Django nor on
Flash based upload solutions. I'll share my ideas here in the hope of
getting some feedback from more knowledgeable and experienced people.
(Or even just some 'I want this too!' replies :) )
You will notice that I make a few assumptions: this is to keep the
(initial) scope of the application under control. These assumptions
are of course debatable:
All right, my idea's so far:
If you want to mass upload multiple files, you are going to have a
model to contain each file in. I.e. the model will contain one
FileField or one ImageField.
Models with multiple (but ofcourse finite) amount of FileFields/
ImageFields are not in need of easy mass uploading imho: if you have a
model with 100 FileFields you are doing something wrong :)
Examples where you would want my envisioned kind of mass upload:
An app that has just one model 'Brochure' with a file field, a
title field (dynamically created from the filename) and a date_added
field.
A photo gallery app with models 'Gallery' and 'Photo'. You pick a
Gallery to add pictures to, upload the pictures and new Photo objects
are created and foreign keys set to the chosen Gallery.
It would be nice to be able to configure or extend the app for your
favorite Flash upload solution. We can pick one of the three above as
a default, but implement the app so that people can easily add
additional implementations (kinda like Django can use multiple
databases). Let it be agnostic to any particular client side solution.
If we need to pick one to start with, maybe pick the one with the
smallest footprint? (smallest download of client side stuff)
The Flash based solutions asynchronously (and either sequentially or
in parallel) POST the files to a url. I suggest that url to be local
to our generic app (so it's the same for every app where you use our
app in). That url will go to a view provided by our generic app.
The view will do the following: create a new model instance, add the
file, OPTIONALLY DO EXTRA STUFF and save the instance.
DO EXTRA STUFF is code that the app that uses our app wants to run.
It doesn't have to provide any extra code, if the model has just a
FileField/ImageField the standard view code will do the job.
But most app will want to do extra stuff I think, like filling in
the other fields: title, date_added, foreignkeys, manytomany, ...
I have not yet thought about a mechanism for DO EXTRA STUFF. Just
wrapping the generic app view came to mind, but that is not developer
friendly, since you would have to write your own url pattern and your
own view. Then you have to tell the Flash solutions to use a new url
etc...
I think something like signals could be used here?
Forms/Admin: I'm still very sketchy on how all this could best be
integrated in the Admin or generic Django forms/widgets/...
(and this is were my lack of Django experience shows):
In the case of the Gallery/Photo app:
You could provide a mass Photo upload widget on the Gallery detail
form. But what if the Gallery instance is not saved yet? The file
upload view won't be able to set the foreignkeys on the Photo
instances. I see that the auth app, when you create a user, first asks
for username and password and only then provides you with a bigger
form to fill in emailadres, pick roles etc. We could do something like
that.
In the case of an app with just one model:
How do you provide a form in the Django admin to do your mass
upload? You can't do it with the detail form of your model, that's
just for one model instance.
There's probably dozens more questions that need to be answered before
I can even start on this app. So please tell me what you think! Give
me input! What do you like? What not? What would you do different? Is
this idea solid? Where is it not?
Thank you!
I just released a simple app for this about a month ago: django-uploadify.
It's basically a Django template tag that acts as a wrapper for the very nifty Uploadify (requires jQuery). Using it is as simple as adding this to your template...
{% load uploadify_tags }{% multi_file_upload ‘/upload/complete/url/’ %}
The tag will fire events (1 per file) on both the client-side and server-side (Django signal) to indicate when an incoming file has been received.
For example, assuming you have a model 'Media' that handles all user-uploaded files...
def upload_received_handler(sender, data, **kwargs):
if file:
new_media = Media.objects.create(
file = data,
new_upload = True,
)
new_media.save()
upload_recieved.connect(upload_received_handler, dispatch_uid=‘whatever.upload_received’)
Check out the wiki for info on how to set it up and create the signal handlers (client/server).
About your conceptual implementation from above, here's a few points of consideration:
Having the app automatically create the "File Model" instance probably isn't as robust as people may already have their own models they're working with
If you want to implement any type of security or authentication, you need an open system and less of an 'auto-create' type
I really think signals/events are the way to handle this, and also handle the 'DO OTHER STUFF' part of what you mentioned.
My conclusion was that multi-upload can never really be a form widget in the sense that Django implements form widgets. 1 file will most likely be represented by 1 model instance (with some exceptions), which means that we end up with a situation where 1 widget can represent N model instances. However Django is setup so that a widget represents 1 value for 1 field in 1 instance. It just doesn't fit for the majority of use-cases to have it as a widget (hence why I went the template tag route).