I am trying to show the related field of the user on the webpage using Django.
I have models:
Models.py
class Companies(models.Model):
company_name = models.TextField()
company_email = models.EmailField()
company_owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.company_name
class Cars(models.Model):
company = models.ForeignKey('Companies', on_delete=models.CASCADE)
car_model = models.TextField()
views.py:
class UserCompanyCars(ListView):
model = Cars
template_name = 'home/company_cars.html'
context_object_name = 'cars'
slug_field ="username"
paginate_by = 100
def get_queryset(self):
company_n = get_object_or_404(Companies, company_owner=self.request.user)
return Cars.objects.filter(company=company_n)
and my html is:
{% extends 'home/base.html' %}
{% block content %}
<h1 class="mb-3"> Cars of {{user.Companies.company_name}}</h1>
{% for car in cars %}
<div class="media-body">
<div class = "article-metadata">
<p class="article-content">{{car.company}}</p>
{{car.car_model}}
<p class="article-content">{{car.car_carry }}</p>
</div>
</div>
{% endfor %}
{% endblock content %}
What I am trying to achieve is to write out "Cars of TestCompany (26)" on the webpage, but I cannot figure out how to get the Company_Name which is owned by the user. I have been trying all those Companies.objects... variations but none of them seem to work.
Try this (sample code taken from my project):
category = get_object_or_404(Category, pk=self.kwargs['pk'])
context['allcategories'] = MyPosts.objects.filter(category=category)
return context
This will filter all posts in the database based on certain categories. You can apply the same solution to your code.
If this solution does not work, please try to give more details about the problem.
Related
trying to display all the ingredients that are associated to a recipe, however:
my models:
class IngredientList(models.Model):
name = models.CharField(max_length=100)
class RecipeList(models.Model):
name = models.CharField(max_length=100)
ingredients = models.ManyToManyField('IngredientList')
instructions = models.TextField(max_length=400)
amount = models.IntegerField()
my views:
from django.shortcuts import render
from .models import IngredientList, RecipeList
def index(request):
ing = RecipeList.objects.all()
context = {'ing': ing}
return render(request, 'myrecipes/home.html', context)
my template:
<div class="card-body">
<h4>{{ details.name}} <span class="badge badge-info">{{details.cuisine}}</span></h4>
<p class="card-text">Ingredients: {{details.ingredients}}</p>
<p class="card-text">Instructions: {{details.instructions}}</p>
<p class="card-text">This makes {{ details.amount}} meals</p>
</div>
my output is "myrecipes.IngredientList.None"
You need to access the queryset of the ingredients, so details.ingredients.all, furthermore you need to iterate over these ingredients, so you work with:
{% for ingredient in details.ingredients.all %}
{{ ingredient }}
{% endfor %}
In the view you can load all the related Ingredients with one extra query with:
def index(request):
ing = RecipeList.objects.prefetch_related('ingredients')
return render(request, 'myrecipes/home.html', {'ing': ing})
This will avoid making an extra query per RecipeList.
I want to present my skill category with their subcategories list.
I am facing issue while fetching the data from models to views.
my code is given below:
model.py Here I create 2 classes SkillCategory and SkillSubCategory
class SkillCategory(models.Model):
id = models.AutoField(primary_key=True)
category = models.CharField(max_length=100)
def __str__(self):
return self.category
class SkillSubCategory(models.Model):
id = models.AutoField(primary_key=True)
category = models.ForeignKey(SkillCategory, on_delete=models.CASCADE)
subcategory = models.CharField(max_length=100)
icon_name = models.CharField(max_length=100)
def __str__(self):
return self.subcategory
views.py Here I define a function based view named as skill which return list of list
def skill(request):
allsubcat = []
skillcat = SkillSubCategory.objects.values()
cat = {c['subcategory'] for c in skillcat}
for c in cat:
skill = SkillSubCategory.objects.filter(subcategory=c)
allsubcat.append([skill])
ctx = {'allsubcat':allsubcat}
return render(request, "my_folio/skill.html", ctx)
skill.html This is the template which should present the Skill like:
Skill Category 1
Skill SubCat 1
Skill SubCat 2
Skill Category 2
Skill SubCat 1
Skill SubCat 2
Skill SubCat 3
Could anyone please help me for the given issue.
Thanks and cheers!!
You Can add related name like this for reverse relationship
class SkillSubCategory(models.Model):
id = models.AutoField(primary_key=True)
category = models.ForeignKey(SkillCategory, on_delete=models.CASCADE, related_name="skill_subcategories")
subcategory = models.CharField(max_length=100)
icon_name = models.CharField(max_length=100)
def __str__(self):
return self.subcategory
in view context you can pass only skills
def skill(request):
skills_categories = SkillCategory.objects.all()
ctx = {'skill_categories': skills_categories}
return render(request, "my_folio/skill.html", ctx)
In template you can iterate like this
<ul>
{% for category in skill_categories %}
<li>{{ category.category }}</li>
<ul>
{% for subcategory in category.skill_subcategories.all %}
<li>{{ subcategory.category }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
Pass only the SkillCategory queryset in the context:
def skill(request):
skill_categories = SkillCategory.objects.all()
ctx = {'skill_categories': skill_categories}
return render(request, "my_folio/skill.html", ctx)
Now in the template you can loop like so:
<ul>
{% for skill_category in skill_categories %}
<li>{{ skill_category.category }}
<ul>
{% for skill_subcategory in skill_category.skillsubcategory_set %}
<li>{{ skill_subcategory.subcategory }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
Where skillsubcategory_set is just the related model name in lowercase with _set appended. Django adds this attribute to your model for each related field to the model (Note: _set will be appended only for Relations of the form One to Many and Many to Many, also you can specify the name using related_name attribute on any ForeignKey, OneToOneField, ManyToManyField, etc.).
models.py
class Blog(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.CharField(max_length=100, unique=True)
post_pic = models.ImageField(upload_to ='media/post_pics/', default =None )
body = models.TextField()
posted = models.DateTimeField(db_index=True, auto_now_add=True)
#author = must be logged in, populate from login details
forms.py
class postForm(forms.Form):
title = forms.CharField(max_length=100)
slug = forms.CharField(max_length=100)
post_pic = forms.ImageField()
body = forms.CharField(widget=SummernoteWidget())
views.py
def write_detail(request):
template_name = 'blog/write.html'
if request.method == 'POST':
post_form = postForm(request.POST)
if post_form.is_valid():
new_post = Blog(title=title,slug=slug,post_pic=post_pic,body=body)
new_post.save()
return HttpResponseRedirect(blog.get_absolute_url())
else:
post_form = postForm()
return render(request, template_name, {'post_form': post_form})
write.html
{% extends 'blog/base.html' %}
{% load static %}
{% block back-img %}'{% static 'blog/assets/img/intro.jpg' %}'{% endblock back-img %}
{% block titdes %}Write{% endblock titdes %}
{% block title %}Write{% endblock title %}
{% block pagedes %}A django powered community blog{% endblock pagedes %}
{% block body%}
<form method = "POST">
{{ post_form.as_p }}
{% csrf_token %}
<button type="submit" class="btn btn-primary">Publish</button>
</form>
{% endblock %}
I have set up this form so that authors can write articles to the blog without accessing the admin panel and I believe it should work but it isn't saving to the database.
I have tried to work on the views over and over but don't know what else to do. Please don't delete my question just ask any question that can help you help me.
in your forms.py
try
from .models import Blog
class postForm(forms.Form):
title = forms.CharField(max_length=100)
slug = forms.CharField(max_length=100)
post_pic = forms.ImageField()
body = forms.CharField(widget=SummernoteWidget())
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic', 'body')
PS. Iam new to Django, i hope this help you.
It looks like you just need to save the form, but you're creating a new Blog object with values that we can't see defined anywhere.
new_post = Blog(title=title,slug=slug,post_pic=post_pic,body=body)
title, slug, etc don't get defined.
What you should do, is change it to a ModelForm so that django does all the hard work;
class postForm(forms.ModelForm):
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic', 'body')
widgets = {
'body': SummernoteWidget(),
}
Then in your view you just need to do;
def write_detail(request):
template_name = 'blog/write.html'
if request.method == 'POST':
post_form = postForm(request.POST)
if post_form.is_valid():
post_form.save()
return HttpResponseRedirect(blog.get_absolute_url())
else:
# GET request
post_form = postForm()
return render(request, template_name, {'post_form': post_form})
The summernote docs for forms (and modelforms) is here
Don't forget, that when using a widget like this that comes with media, you need to add the form's media to the template.
You can access it in the HTML using either {{ form.media }} to get all CSS and JS, or individually as {{ form.media.js }} and {{ form.media.css }}
You can see how they do it in the summernote app playground
class postForm(forms.ModelForm):
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic','body')
widgets = {
'body':SummernoteWidget(),
}
Sorry guys you can actually use django summer note with a model form. I used it before but the editor was not appearing so I changed it to the one I previously posted but after reading another answer on stack overflow. I found out that I didn't add this code below to my HTML files or just inside my base.html
<!-- include summernote css/js-->
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.js"></script>
Thanks guys
I want to update the User and Lab model. I am able to see the form but it is not pre-populated with existing database information even after setting the instance parameter. If I submit a blank form then all fields are reset to blank values in the database. I have tried several solutions available online but nothing works.
My queries -
How do I pre-populate my form with existing data?
If the user doesnt fill out a particular field, I want the previous information to be stored as it is and not as a blank value. How do I achieve this?
I have the following models.py
class Lab(models.Model):
uid = models.OneToOneField(User, on_delete=models.CASCADE)
company=models.CharField(max_length=200,blank=True)
#receiver(post_save, sender=User)
def create_lab_profile(sender, instance, created, **kwargs):
if created:
Lab.objects.create(uid=instance)
#receiver(post_save, sender=User)
def save_lab_profile(sender, instance, **kwargs):
instance.lab.save()
Forms.py
class UserForm(forms.ModelForm):
email=forms.EmailField(max_length=300)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email',)
class LabForm(forms.ModelForm):
class Meta:
model = Lab
fields = ('company',)
views.py
#login_required
def update_user_details(request,pk):
if request.method == 'POST':
user_form = UserForm(request.POST,instance=request.user)
lab_form = LabForm(request.POST,instance=request.user.lab)
if user_form.is_valid() and lab_form.is_valid():
user_form.save()
lab_form.save()
messages.success(request,'Your profile was successfully updated!')
return redirect('user_details')
else:
messages.error(request,('Please correct the error below.'))
else:
user_form = UserForm(instance=request.user)
lab_form = LabForm(instance=request.user.lab)
return render(request, 'update_user_details.html', {'user_form': user_form,'lab_form': lab_form})
template -
{% extends 'base.html' %}
{% block content %}
{% csrf_token %}
<H3> Update Personal information - </H3>
<br>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
{{ lab_form.as_p }}
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
{% endblock %}
Any help/suggestions will be appreciated!
everyone!
Implementing the edit/add functions to the app, I found that Django ignores my clean_<field_name> method in some classes. When I tried to debug it I found out that the methods are not even called. Here are the relevant code snippets:
models.py
class StoredItem(models.Model):
item = models.ForeignKey(Item)
quantity = models.IntegerField(default=0)
class Meta:
ordering = ["item"]
def __str__(self):
return "{0} - {1}, {2} pcs.".format(self.item.serial, self.item.name, self.quantity)
def get_absolute_url(self):
return reverse('almacen:storeditem-detail', args=[str(self.id)])
forms.py
# Stored items related forms
class NewOrEditStoredItemForm(forms.Form):
item = forms.ModelChoiceField(queryset=StoredItem.objects.all())
quantity = forms.IntegerField()
def clean_item(self):
item = self.cleaned_data['item']
storeds = map(lambda x: x.item, StoredItem.objects.all())
if item in storeds:
raise ValidationError(_("This item has already been stored - you only can change its quantity in the stock!"))
def clean_quantity(self):
quantity = self.cleaned_data['quantity']
if quantity < 0:
raise ValidationError(_("Items quantity can not be negative!"))
return quantity
views.py
# Stored items related ---------------------------------------------------------------------
class CreateStoredItem(CreateView):
model = StoredItem
fields = '__all__'
class UpdateStoredItem(UpdateView):
model = StoredItem
fields = '__all__'
storeditem_form.html
{% extends 'base_template.html' %}
{% block header %}
<h2 id="center">Stocked item add/delete </h2>
{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit"/>
</form>
{% endblock %}
EDIT
Resolved by rewriting the classes into functions. For classes I was recommended to use validators, but anyway, functions worked as I need.
Resolved by rewriting the classes into functions. For classes I was recommended to use validators, but anyway, functions worked as I needed