I have three apps (Internship, UserProfile and Infrastructure) in my django project. I have made models Profile and StudentProject in UserProfile Model. The StudentProject Model contains two foreign key-> user and Lab (this model is defined in the Infrastructure model). In a template(details.html file) in Infrastructure app, i want to retrieve all StudentProjects who have their foreign key as the lab whose details are currently being shown. I am unable to bring the student projects created here. Please help someone. I have already tried to use filter but it doesn't work!
userprofile/models.py file
from django.conf import settings
from django.db import models
from django.core.urlresolvers import reverse
from infrastructure.models import Lab
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
type = models.CharField(max_length=100)
profile_picture = models.FileField()
skills = models.CharField(max_length=1000)
def get_absolute_url(self):
return reverse('userprofile:index')
def __str__(self):
return self.name
class StudentProject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
project_picture = models.FileField()
lab = models.ForeignKey(Lab)
mentor = models.CharField(max_length=100)
domain = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('userprofile:index')
infrastructure/models.py file
from django.db import models
from django.core.urlresolvers import reverse
class Lab(models.Model):
name = models.CharField(max_length=100)
department = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
lab_logo = models.FileField()
def get_absolute_url(self):
return reverse('infrastructure:details', kwargs={'pk': self.pk})
def __str__(self):
return self.name
infrastructure/templates/details.html
->This is where i want all student projects of lab to be shown
{% extends 'infrastructure/base.html' %}
{% block body %}
<h1>This is details page</h1>
<img src="{{ lab.lab_logo.url }}" style="width: 300px;">
<h1>{{ lab.name }}</h1>
<h2>{{lab.projects}}</h2>
{% endblock %}
infrastructure/views.py file
from django.core.urlresolvers import reverse_lazy
from django.views import generic
from infrastructure.models import Lab
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class IndexView(generic.ListView):
template_name = 'infrastructure/index.html'
context_object_name = 'all_labs'
def get_queryset(self):
return Lab.objects.all()
class DetailView(generic.DetailView):
model = Lab
template_name = 'infrastructure/details.html'
class LabCreate(generic.CreateView):
model = Lab
fields = ['name', 'department', 'description', 'lab_logo']
class LabUpdate(generic.UpdateView):
model = Lab
fields = ['name', 'department', 'description', 'lab_logo']
class LabDelete(DeleteView):
model = Lab
success_url = reverse_lazy('infrastructure:index')
infrastructure/urls.py file
from django.conf.urls import url
from . import views
app_name = 'infrastructure'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='details'),
url(r'^lab/add/$', views.LabCreate.as_view(), name='lab-add'),
url(r'^lab/(?P<pk>[0-9]+)/$', views.LabUpdate.as_view(), name='lab-update'),
url(r'^lab/(?P<pk>[0-9]+)/delete/$', views.LabDelete.as_view(), name='lab-delete'),
]
userprofile/views.py file
from django.contrib.auth import login, authenticate, logout
from django.http import request
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from .models import Profile, StudentProject
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .forms import UserForm
from django.views import generic
from django.views.generic import View
class IndexView(generic.TemplateView):
template_name = 'userprofile/index.html'
context_object_name = 'user_profile'
def get_queryset(self):
return request.user.get_profile()
class ProfileCreate(CreateView):
model = Profile
fields = ['user', 'name', 'type', 'profile_picture', 'skills']
class ProfileUpdate(UpdateView):
model = Profile
fields = ['user', 'name', 'type', 'profile_picture', 'skills']
class StudentProjectCreate(CreateView):
model = StudentProject
fields = ['user', 'title', 'project_picture', 'lab', 'mentor', 'domain', 'description']
class StudentProjectUpdate(UpdateView):
model = StudentProject
fields = ['user', 'title', 'project_picture', 'lab', 'mentor', 'domain', 'description']
class StudentProjectDelete(DeleteView):
model = StudentProject
success_url = reverse_lazy('userprofile:index')
def logout_view(request):
logout(request)
return render(request, 'userprofile/logout.html')
# for new user
class UserFormView(View):
form_class = UserForm
template_name= 'internship/registration_form.html'
# display blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# process from data
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
# cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
# return User object if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('userprofile:profile-add')
return render(request, self.template_name, {'form': form})
userprofile/urls.py file
from django.conf.urls import url, include
from django.contrib.auth import views as auth_views
from userprofile import views
app_name = 'userprofile'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^profile/add/$', views.ProfileCreate.as_view(), name='profile-add'),
url(r'^profile/(?P<pk>[0-9]+)/$', views.ProfileUpdate.as_view(), name='profile-update'),
url(r'^logout$', views.logout_view, name='logout_view'),
url(r'^login/$', auth_views.login, {'template_name': 'userprofile/login.html'}),
url(r'^register/$', views.UserFormView.as_view(), name='register'),
url(r'^studentproject/add/$', views.StudentProjectCreate.as_view(), name='student-project-add'),
url(r'^studentproject/(?P<pk>[0-9]+)/$', views.StudentProjectUpdate.as_view(), name='student-project-update'),
url(r'^studentproject/(?P<pk>[0-9]+)/delete/$', views.StudentProjectDelete.as_view(), name='student-project-delete'),
]
Basically, you need to add related_name argument to your declaration of Lab Field in StudentProject Model. That will make children accessible from parent Model further:
class StudentProject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
project_picture = models.FileField()
lab = models.ForeignKey(Lab, related_name=projects)
...
And now, in your template, you can easily iterate over your current lab's projects:
{% extends 'infrastructure/base.html' %}
{% block body %}
<h1>This is details page</h1>
<img src="{{ lab.lab_logo.url }}" style="width: 300px;">
<h1>{{ lab.name }}</h1>
{% for project in lab.projects_set.all %}
<h2>{{project.title}}</h2>
{% endfor %}
{% endblock %}
Related
i am building a blog in Django and where register user can write blog articles . I want to display posts that are associated with certain categories on one page. i tried to do that but it does not show the post associated to the article. here is my files
models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from datetime import datetime, date
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
def get_absolute_url(self):
# return reverse('article', args=(str(self.id)))
return reverse('home') # go to home page after article submission
class Post(models.Model):
title = models.CharField(max_length=255)
tags = models.CharField(max_length=255, default="Ryan's World")
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateField(auto_now_add=True)
category = models.CharField(max_length=255, default="uncategorized")
def __str__(self):
return self.title+' | '+str(self.author)
def get_absolute_url(self):
# return reverse('article', args=(str(self.id)))
return reverse('home') # go to home page after article submission
views.py
created function based view
from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post, Category
from .forms import PostForm, EditForm
from django.urls import reverse_lazy
class HomeView(ListView):
model = Post
template_name = 'home.html'
ordering = ['-id']
def CategoryView(request, cats):
category_posts = Post.objects.filter(category=cats)
return render(request, 'categories.html', {'cats':cats ,'category_posts': category_posts })
. . .
urls.py
from django.urls import path
# from . import views
from .views import HomeView, ArticleDetailView, AddPostView, UpdatePostView, DeletePostView, AddCategoryView, CategoryView
urlpatterns = [
# path('', views.home , name='home'),
path('', HomeView.as_view(), name="home"),
path('article/<int:pk>', ArticleDetailView.as_view(), name="article"),
path('add_post/', AddPostView.as_view(), name='add_post'),
path('add_category/', AddCategoryView.as_view(), name='add_category'),
path('article/edit/<int:pk>', UpdatePostView.as_view(), name="updatearticle"),
path('article/<int:pk>/remove', DeletePostView.as_view(), name="deletearticle"),
path('category/<str:cats>/', CategoryView, name='category')
]
forms.py
from django import forms
from .models import Post, Category
choices = Category.objects.all().values_list('name','name')
choice_list = []
for item in choices:
choice_list.append(item)
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'tags', 'author','category' ,'body')
widgets = {
'title': forms.TextInput(attrs={'class':'form-control', 'placeholder': 'this is placeholder'}),
'tags': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.Select(attrs={'class':'form-control'}),
'category': forms.Select( choices = choice_list, attrs={'class':'form-control'}),
'body': forms.Textarea(attrs={'class':'form-control'}),
}
I can't figure out why my data won't display in my user.html template. From reviewing the code it looks like everything is linked correctly. The users.html page is showing up on the website minus the information about {{ user.order_set.all }}. I have highlighted the code I believe relates to the issue. Any guidance would be greatly appreciated, thanks!
user.html - html for displaying the data
{% extends "fuisce/base.html" %}
{% block content %}
**{{ user.order_set.all }}**
{% endblock content %}
views.py - order
from django.shortcuts import render, HttpResponseRedirect
from django.urls import reverse
# Create your views here.
from carts.models import Cart
from .models import Order
from users.models import Profile
from .utils import id_generator
**def orders(request):
context = {}
template = "orders/user.html"
return render(request, template, context)**
def checkout(request):
try:
the_id = request.session['cart_id']
cart = Cart.objects.get(id=the_id)
except:
the_id = None
return HttpResponseRedirect(reverse("cart"))
new_order, created = Order.objects.get_or_create(cart=cart)
if created:
new_order.order_id = id_generator()
new_order.save()
my_p = Profile.objects.get(user=request.user)
new_order.user = my_p
new_order.save()
if new_order.status == "Finished":
# cart.delete()
del request.session['cart_id']
del request.session['items_total']
return HttpResponseRedirect(reverse("cart"))
context = {}
template = "fuisce/about.html"
return render(request, template, context)
models.py - orders
from django.db import models
# Create your models here.
from carts.models import Cart
from users.models import Profile
STATUS_CHOICES =(
("Started", "Started"),
("Abandoned", "Abandoned"),
("Finished", "Finished"),
)
class Order(models.Model):
**user = models.ForeignKey('users.Profile', null=True, blank=True, on_delete=models.CASCADE)**
order_id = models.CharField(max_length=120, default='ABC', unique=True)
cart = models.ForeignKey('carts.Cart', on_delete=models.CASCADE)
status = models.CharField(max_length=120, choices=STATUS_CHOICES, default="Started")
sub_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
tax_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
final_total = models.DecimalField(default=10.99, max_digits=1000, decimal_places=2)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __string__(self):
return self.order_id
urls.py
from django.urls import path
from . import views
from carts import views as cart_views
from orders import views as order_views
urlpatterns = [
path('', views.home, name='fuisce-home'),
path('subscription/', views.subscription, name='fuisce-subscription'),
path('oneoff/', views.oneoff, name='fuisce-oneoff'),
path('about/', views.about, name='fuisce-about'),
path('contact/', views.contact, name='fuisce-contact'),
path('cart/', cart_views.view, name='cart'),
path('cart/<int:id>/', cart_views.remove_from_cart, name='remove_from_cart'),
path('cart/<slug>/', cart_views.add_to_cart, name='add_to_cart'),
path('checkout/', order_views.checkout, name='checkout'),
**path('orders/', order_views.orders, name='user_orders'),**
]
Based on the comments to the question, it seems you have a ForeignKey field to Profile and not to User.
Either change your ForeignKey from Profile to User like this:
class Order(models.Model):
user = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
null=True,
blank=True)
Or use a different lookup in your template:
{{ user.profile.order_set.all }}
I Need to Restrict the Options in a Select Field of a Django Form for not staff users.
So these are my models.py:
#!/usr/bin/python3
from django.db import models
from django.urls import reverse
class Extension(models.Model):
username = models.CharField(primary_key=True, max_length=200, help_text='')
callerid = models.CharField(max_length=200, help_text='')
extension = models.CharField(max_length=3, help_text='')
firstname = models.CharField(max_length=200, help_text='')
lastname = models.CharField(max_length=200, help_text='')
password = models.CharField(max_length=200, help_text='')
context = models.ForeignKey('Context', on_delete=models.SET_NULL, null=True)
def get_absolute_url(self):
return reverse('extension-detail', args=[str(self.username)])
def my_get_absolute_url(self):
return reverse('my-extension-detail', args=[str(self.username)])
def __str__(self):
return self.username
class Context(models.Model):
name = models.CharField(primary_key=True, max_length=200, help_text='')
countryprefix = models.CharField(max_length=200, help_text='')
cityprefix = models.CharField(max_length=200, help_text='')
number = models.CharField(max_length=200, help_text='')
extensionsfrom = models.CharField(max_length=200, help_text='')
extensionstill = models.CharField(max_length=200, help_text='')
portscount = models.CharField(max_length=200, help_text='')
def get_absolute_url(self):
return reverse('context-detail', args=[str(self.name)])
def my_get_absolute_url(self):
return reverse('my-context-detail', args=[str(self.name)])
def __str__(self):
return self.name
views.py:
#!/usr/bin/python3
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.models import Permission
from catalog.models import Extension, Context
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
class ExtensionCreate(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = Extension
fields = '__all__'
permission_required = 'catalog.add_extension'
class ExtensionUpdate(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
model = Extension
fields = '__all__'
permission_required = 'catalog.change_extension'
class ExtensionDelete(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
model = Extension
success_url = reverse_lazy('extensions')
permission_required = 'catalog.delete_extension'
urls.py:
#!/usr/bin/python3
from . import views
from django.urls import path
urlpatterns = [
path('', views.index, name='index'),
path('extensions/', views.ExtensionListView.as_view(), name='extensions'),
path('extension/<str:pk>', views.ExtensionDetailView.as_view(), name='extension-detail'),
path('extension/create/', views.ExtensionCreate.as_view(), name='extension-create'),
path('extension/<str:pk>/update/', views.ExtensionUpdate.as_view(), name='extension-update'),
path('extension/<str:pk>/delete/', views.ExtensionDelete.as_view(), name='extension-delete'),
path('myextensions/', views.ExtensionsByUserListView.as_view(), name='my-extensions'),
path('myextension/<str:pk>', views.ExtensionsByUserDetailView.as_view(), name='my-extension-detail'),
path('contexts/', views.ContextListView.as_view(), name='contexts'),
path('context/<str:pk>', views.ContextDetailView.as_view(), name='context-detail'),
path('context/create/', views.ContextCreate.as_view(), name='context-create'),
path('context/<str:pk>/update/', views.ContextUpdate.as_view(), name='context-update'),
path('context/<str:pk>/delete/', views.ContextDelete.as_view(), name='context-delete'),
path('mycontexts/', views.ContextByUserListView.as_view(), name='my-contexts'),
path('mycontext/<str:pk>', views.ContextByUserDetailView.as_view(), name='my-context-detail'),
]
template:
{% extends "base_generic.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
{% endblock %}
In this is how it looks like:
The Username is always the same as one of the contexts.
Only Staff User can create a new Context and new Users.
The users then should add their extensions.
While employees should be able to select the context when creating a new extension, customers should only be able to see or select their context in the list.
Therefore it is needed to filter the Select-attribute for non-staff members so that only the user's context is visible, which is equal to his Username.
Alternatively, I want to prepopulate and hide the context form field with the Username (=own context)
How can I do either of this in the easiest way possible?
Here is what I tried myself so far:
Like described in this how-to: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms#Renew-book_form_using_a_Form_and_function_view I Defined a Form in forms.py:
#!/usr/bin/python3
from django import forms
class MyExtensionCreateForm(forms.Form):
# username = forms.CharField(help_text="")
# callerid = forms.CharField(help_text="")
# context = forms.CharField(help_text="")
firstname = forms.CharField(help_text="")
lastname = forms.CharField(help_text="")
extension = forms.CharField(help_text="")
password = forms.CharField(help_text="")
def clean_data(self):
data = self.cleaned_data
# Remember to always return the cleaned data.
return data
I then added the folowing to the views.py:
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
from catalog.forms import MyExtensionCreateForm
def MyExtensionCreate(request):
# extension = get_object_or_404(Extension)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = MyExtensionCreateForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required
form.firstname = form.cleaned_data['firstname']
form.lastname = form.cleaned_data['lastname']
form.extension = form.cleaned_data['extension']
form.password = form.cleaned_data['password']
# Prepopulated Fields
form.context = request.user
form.callerid = str(form.cleaned_data['firstname'])+" "+str(form.cleaned_data['lastname'])+" "+str(form.cleaned_data['extension'])
form.username = str(request.user)+"_"+str(form.cleaned_data['extension'])
form.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('my-extensions'))
# If this is a GET (or any other method) create the default form.
else:
form = MyExtensionCreateForm({'context': request.user})
context = {
'form': form,
}
return render(request, 'catalog/extension_form-by-user.html', context)
# class MyExtensionCreate(LoginRequiredMixin, CreateView):
# model = Extension
# fields = '__all__'
# form_class = MyExtensionCreateForm
Then I added a new URL to URL patterns in urls.py and added the new Link to the base_generic.html
path('myextensions/create/', views.MyExtensionCreate, name='my-extension-create'),
<li>Add Extension</li>
I can view the form, and if I add the context field to the visible form fields, I can see that the context will initially fill with the logged-in username (See First Picture Below). But as soon as I submit the form I'll get Error's no matter what I try, So basically the GET is working, but the POST isn't really.
See Folowing Pictures:
I was able to Filter the Choices by the Username in the ModelForm but since then I'm not able to save the form to the database anymore.
Here is the new Stack Post with the Resolution of this Post here and the new Question/Problem.
Django: saving the Form does not work (The ModelForm Filters the ForeignKey choices by request.user)
I am getting the error:
NOT NULL constraint failed: films_comment.film_id
On the comments page there is a form field called body for the comment itself, I also need it to store this comment against the user and the film.
Models:
from django.db import models
from django.urls import reverse
class Film(models.Model):
title = models.CharField(max_length=200)
director = models.CharField(max_length=200)
description = models.CharField(max_length=200)
pub_date = models.DateField('date published')
def get_absolute_url(self):
return reverse('films:detail', kwargs={'pk' : self.pk})
class Comment(models.Model):
# user = models.ForeignKey(User, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
Views:
from django.views import generic
from .models import Film, Comment
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class IndexView(generic.ListView):
# model = Film
template_name = 'films/index.html'
# context_object_name = 'object_list'
def get_queryset(self):
return Film.objects.all()
class DetailView(generic.DetailView):
model = Film
template_name = 'films/detail.html'
class CommentCreate(CreateView):
model = Comment
fields = ['body']
Urls:
app_name = 'films'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
# path('<int:film_id>/comment', views.add_comment, name='add_comment'),
path('<int:pk>', views.DetailView.as_view(), name='detail'),
path('<int:film_id>/comment/', views.CommentCreate.as_view(), name='add_comment'),
]
Link on details page for adding a comment:
Leave a comment
comment_form.py:
<form action="" method="post">
{% csrf_token %}
{% include 'films/form-template.html' %}
<button type="submit">Submit</button>
</form>
Form template:
{% for field in form %}
{{field.errors}}
<label>{{ field.label_tag }}</label>
{{ field }}
{% endfor %}
forms.py
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body',)
You need to override view's form_valid method to update new comment instance with current user and film:
class CommentCreate(CreateView):
model = Comment
fields = ['body']
def form_valid(self, form):
film = Film.objects.get(pk=self.kwargs['film_id'])
form.instance.user = self.request.user
form.instance.film = film
return super(CommentCreate, self).form_valid(form)
To fix "No URL redirect to" you can add get_absolute_url() method to the Comment model:
def get_absolute_url(self):
return reverse('detail', kwargs={'pk': self.film.pk})
I am using django 1.11.6 and python 3.6.2
I'm new to django and there is no one to help me where i live so you guys are all my hope
in my django application in the add song section i faced an error
error message =
IntegrityError at /music/album/5/AddSong/ NOT NULL constraint failed:
music_song.album_id
here is my views file:
from django.views import generic
from django.views.generic import View
from .forms import UserForm
from django.views.generic.edit import CreateView,UpdateView,DeleteView
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate, login
from .models import Album, Song
from django.core.urlresolvers import reverse_lazy
class IndexView(generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
return Album.objects.all()
class DetailView(generic.DetailView):
model = Album
template_name = 'music/detail.html'
context_object_name = 'album'
class AlbumCreate(CreateView):
model = Album
fields = ['artist', 'album_title', 'genre', 'album_logo']
class SongCreate(CreateView):
model = Song
fields = ['song_title', 'file_type']
class AlbumUpdate(UpdateView):
model = Album
fields = ['artist', 'album_title', 'genre', 'album_logo']
class AlbumDelete(DeleteView):
model = Album
success_url = reverse_lazy('music:index')
class UserFormView(View):
form_class = UserForm
template_name = 'music/registration_form.html'
#display a blank form
def get(self,request):
form = self.form_class(None)
return render(request,self.template_name, {"form": form})
#procces form data
def post(self,request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
#cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
#returns User objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request,user)
return redirect('music:index')
return render(request,self.template_name, {"form": form})
and here is my models.py :
from django.db import models
from django.core.urlresolvers import reverse
class Album(models.Model):
artist = models.CharField(max_length=250)
album_title = models.CharField(max_length=500)
genre = models.CharField(max_length=100)
album_logo = models.FileField()
def get_absolute_url(self):
return reverse('music:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.album_title + ' - ' + self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
is_favorite = models.BooleanField(default=False)
# song_file = models.FileField(null=True)
def __str__(self):
return self.song_title
def get_absolute_url(self):
return reverse('music:detail', kwargs={'pk': self.album.id})
urls.py:
from django.conf.urls import url
from . import views
app_name = 'music'
urlpatterns = [
# /music/
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^register/$', views.UserFormView.as_view(), name='register'),
# /music/album/54
url(r'^album/(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
# music/album/add
url(r'album/add/$', views.AlbumCreate.as_view(), name='album-add'),
# music/album/3/AddSong
url(r'album/(?P<pk>[0-9]+)/AddSong/$', views.SongCreate.as_view(), name='song-add'),
# music/album/2/update/
url(r'album/(?P<pk>[0-9]+)/AlbumUpdate/$', views.AlbumUpdate.as_view(), name='album-update'),
# music/album/2/delete/
url(r'album/(?P<pk>[0-9]+)/AlbumDelete/$', views.AlbumDelete.as_view(), name='album-delete'),
]
For creating forms I used Django built-in forms,I had to create one for adding albums and another for adding the album's songs
Here is my album_form.html screenshot
and here is my form-template.html screenshot:
and here is my song_form.html screenshot
In the form_valid method, you should fetch the album pk from the url kwargs and set the album on the form instance.
from. django.shortcuts import get_object_or_404
class SongCreate(CreateView):
model = Song
fields = ['song_title', 'file_type']
def form_valid(self, form):
album = get_object_or_404(Album, pk=self.kwargs['pk']
form.instance.album = album
return super(SongCreate, self).form_valid(form)