Overriding Django profiles' profile_detail view - django

I installed django profiles/registration and everything seems to be fine. When a user registers their profile is created also. Now what i want to do is query another Model which is Company based on the user id of User. I dont want to change django-profiles view but add the extra field on urls to match and query Company model. When i hardcode the url (ex:put the id number of the userprofile like so userprofile=1, it works.). So when a user is logged in and goes to profile detail page Company assigned to them is queried based on their user.id.
class UserProfile(models.Model):
user = models.OneToOneField(User)
#email = models.CharField(max_length=200, blank=True, null=True)
# Other fields here
#company = models.ForeignKey(Company,blank=True,null=True)
#office = models.CharField(max_length=200, blank=True, null=True)
def __unicode__(self):
return self.user.username
class Company(models.Model):
userprofile = models.ForeignKey(UserProfile, null=True, blank=True)
comp_name = models.CharField(max_length=200,blank=True,null=True)
comp_address = models.CharField(max_length=200,blank=True, null=True)
comp_email = models.CharField(max_length=200,blank=True, null=True)
comp_zip = models.IntegerField(blank=True, null=True)
comp_phone = models.IntegerField(blank=True, null=True)
comp_city = models.CharField(max_length=200,blank=True, null=True)
#comp_state = models.USStateField(blank=True, null=True
comp_state = models.CharField(blank=True, max_length=2)
compwebsite = models.URLField(max_length=200, blank=True, null=True)
twitterurl = models.URLField(max_length=200, blank=True, null=True)
facebookurl = models.URLField(max_length=200, blank=True, null=True)
def __unicode__(self):
return self.comp_name
url(r'^profiles/(?P<username>\w+)/$', 'profiles.views.profile_detail', {'extra_context':{'queryset':Company.objects.filter(userprofile=request.user.id)}},),

You might want to call it from inside a view
from *** import profile_detail
def my_view(request, username):
extra_context = {}
return profile_detail(request, queryset=Company.objects.filter(userprofile=request.user.id),
template_name="my_template.html",
paginate_by=20,
extra_context=extra_context)

Related

Django class based view, save in another model after CreateView

I have a create view (Loan_assetCreateView(generic.CreateView)) where I save if an asset is going to be loaned and when it will be returened in a model called Loan_asset(models.Model). Then I have the asset in a diffrent model Asset(model.Model). I would like to once I have saved my data in my Loan_assetCreateView(generic.CreateView) that is set the value in Asset.is_loaned to True. How can I do that?
My models.py:
class Asset(models.Model):
# Relationships
room = models.ForeignKey("asset_app.Room", on_delete=models.SET_NULL, blank=True, null=True)
model_hardware = models.ForeignKey("asset_app.Model_hardware", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=30)
serial = models.CharField(max_length=30, unique=True, blank=True, null=True, default=None)
mac_address = models.CharField(max_length=30, null=True, blank=True)
purchased_date = models.DateField(null=True, blank=True)
may_be_loaned = models.BooleanField(default=False, blank=True, null=True)
is_loaned = models.BooleanField(default=False, blank=True, null=True)
missing = models.BooleanField(default=False, blank=True, null=True)
notes = HTMLField(default="")
ip = models.CharField(max_length=90, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Loan_asset(models.Model):
# Relationships
asset = models.ForeignKey("asset_app.Asset", on_delete=models.SET_NULL, blank=True, null=True)
loaner_type = models.ForeignKey("asset_app.Loaner_type", on_delete=models.SET_NULL, blank=True, null=True)
location = models.ForeignKey("asset_app.Locations", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
loaner_name = models.CharField(max_length=60)
loaner_address = models.TextField(max_length=100, null=True, blank=True)
loaner_telephone_number = models.CharField(max_length=30)
loaner_email = models.EmailField()
loaner_quicklink = models.URLField(null=True, blank=True)
loan_date = models.DateField()
return_date = models.DateField()
notes = HTMLField(default="")
returned = models.BooleanField(default=False, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
class Meta:
pass
def __str__(self):
return str(self.loaner_name)
def get_absolute_url(self):
return reverse("asset_app_loan_asset_detail", args=(self.pk,))
def get_update_url(self):
return reverse("asset_app_loan_asset_update", args=(self.pk,))
my urls.py
`path("asset_app/loan_asset/create/", views.Loan_assetCreateView.as_view(), name="asset_app_loan_asset_create")`,
my views.py
class Loan_assetCreateView(generic.CreateView):
model = models.Loan_asset
form_class = forms.Loan_assetForm
Here are some options:
override form_valid method that's being called in post method implementation, so that after form will be validated (model instance saved), you'll be able to set the flag through foreign key/by creating Asset instance:
...
def form_valid(self, form):
self.object = form.save()
if self.object.asset:
self.object.asset.is_loaned = True
else:
self.object.asset = Asset.objects.create(is_loaned=True)
return HttpResponseRedirect(self.get_success_url())
use Django signals:
#receiver(post_save, sender=Loan_asset)
def create_transaction(sender, instance, created, **kwargs):
if created:
Asset.objects.create(is_loaned=True)
You can override the post method in your Loan_assetCreateView.
class Loan_assetCreateView(generic.CreateView):
model = models.Loan_asset
form_class = forms.Loan_assetForm
def post(request, *args, **kwargs):
response = super().post(request, *args. **kwargs)
# Do your thing
return response

Django: Assign Route to Order Based on User Input of Location

In my create order view, I am trying to automatically assign the respective route based on the location the user inputs. Basically, every location in the system has a FK to a route. There are many locations within a route. If you select a location to send products to, the route should automatically be tied to.
Currently I am able to see the route for an order in my order_list.html page, but when I view the order in the Django admin, the route is not assigned to the order but the location is.
I want it to work similarly to how you would assign the current logged in user to an order:
form.instance.user = request.user
I tried using:
form.instance.company = request.user.company
But I am getting an attribute error:
'WSGIRequest' object has no attribute 'location'
Here is my full order_create function:
orders/views.py:
#login_required(login_url='account_login')
def order_create(request):
"""
A function that takes the users cart with products, then converts the cart into an
OrderForm. Then saves the form/order to the database.
"""
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
form.instance.user = request.user
form.instance.company = request.user.company
form.instance.route = request.location.route
order = form.save()
for item in cart:
OrderItem.objects.create(order=order,
product=item['product'],
price=item['price'],
quantity=item['quantity'])
# clear the cart
cart.clear()
return render(request,
'orders/order/created.html',
{'order': order,
})
else:
form = OrderCreateForm()
return render(request,
'orders/order/create.html',
{'cart': cart, 'form': form})
Here are the Location, Route and Order models:
orders/models.py:
class Route(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Locations(models.Model):
"""
A model to represent a location or locations a company has.
"""
name = models.CharField(max_length=100)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
route = models.ForeignKey(Route, on_delete=models.DO_NOTHING)
store_number = models.CharField(max_length=15, blank=True, null=True)
address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, blank=True, null=True)
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
route = models.ForeignKey(Route, on_delete=models.DO_NOTHING, blank=True, null=True)
location = models.ForeignKey(Locations, on_delete=models.DO_NOTHING, blank=True, null=True)
company = models.ForeignKey(Company, on_delete=models.DO_NOTHING, blank=True, null=True)
delivery_date = models.DateField()
address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
delivered = models.BooleanField(default=False)
and then finally the company and user model in my accounts app that are used as foreign keys in the orders app.
accounts/models.py:
class Company(models.Model):
"""
A model to represent companies that can operate within the system, which multiple users are apart of.
"""
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
city = models.CharField(max_length=25)
state = USStateField()
zip = models.CharField(max_length=5)
admin = models.ForeignKey("accounts.User", on_delete=models.DO_NOTHING, related_name="company_admin", blank=True, null=True)
class User(AbstractBaseUser, PermissionsMixin):
"""
A model to represent a User of the system.
"""
ROLE_CHOICES = (
('ADMIN', "Admin"),
('MANAGER', "Manager"),
('DRIVER', "Driver"),
('PRODUCTION', "Production")
)
email = models.EmailField(max_length=254, unique=True)
phone = models.CharField(max_length=15, help_text="(123)-123-1234", blank=True, null=True)
first_name = models.CharField(max_length=254, null=True, blank=True)
last_name = models.CharField(max_length=254, null=True, blank=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, blank=True, null=True)
role = models.CharField(max_length=10, choices=ROLE_CHOICES, default=None, blank=True, null=True)
is_employee = models.BooleanField(default=False, blank=True, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)

Django ManyToManyField not showing in admin

As this questions says, I am having trouble displaying a ManyToManyField in the django admin page.
The m2m field that I'm having trouble displaying is comics in the Gig model.
Here is the code for my project:
#models.py file
class Host(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='host')
name = models.CharField("Venue Name", max_length=200)
slug = models.SlugField(allow_unicode=True, blank=True, null=True)
description = models.TextField("Brief Venue Description - [50 Characters Max]", max_length=50, blank=True)
profile_pic = models.ImageField("Profile Picture", upload_to='host/profile_pics',blank=True)
class Gig(models.Model):
host = models.ForeignKey(Host, on_delete=models.CASCADE, blank=True, related_name='host_gigs')
title = models.CharField("Gig Title",max_length=50, null=True)
date_time = models.DateTimeField("Date/Time of Gig", null=True, blank=True)
description = models.TextField("Describe this gig", max_length=150, blank=True)
instructions = models.CharField('Instructions for accepted comics', max_length=200, blank=True, null=True)
comics = models.ManyToManyField("comic.Comic", through='comic.ComicGig',related_name='gig_comics', default=" ")
#in separate app
#models.py
class Comic(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, related_name='comic')
dob = models.DateField("Date of Birth", null=True, blank=True)
mobile = PhoneNumberField(null=True, blank=True)
slug = models.SlugField(allow_unicode=True, blank=True, null=True)
class ComicGig(models.Model):
thegig = models.ForeignKey('host.Gig', on_delete=models.CASCADE, default="", related_name='comic_gig')
comic = models.ForeignKey(Comic, on_delete=models.CASCADE, default="")
approved_comic = models.BooleanField(default=False, null=True)
def approve(self):
self.approved_comic = True
self.save()
Here is my Host admin.py file:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('host', 'title',)
filter_horizontal = ('comics',)
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "comics":
kwargs["queryset"] = Gig.objects.filter(comic_gig__approved_comic=True)
return super().formfield_for_manytomany(db_field, request, **kwargs)
admin.site.register(Host)
admin.site.register(Gig, AuthorAdmin)
Here is a picture of my Host model in the admin
Here is a picture of my ComicGig model in the admin

Multiple HTML option selection not working

I am developing a task management system using the django framework where supervisors can log in and assign tasks to multiple users using Django many to many field. When I log in to the admin portal, I can select multiple users at the same time which saves to the database well. But when I use the front end template, I am able to select multiple users but the selected options never get saved in the database and instead the field will be blank when viewing from the database table.
Here is my Model:
from django.contrib.auth.models import User
class Task(models.Model):
task_title = models.CharField(max_length=30, blank=True, null=True)
unit = models.ForeignKey(Unit, blank=True, null=True)
audit_phase_choice = (
('Pre Engagement', 'Pre Engagement'),
('Understanding Entity', 'Understanding Entity'),
('Risk Assessment', 'Risk Assessment'),
('Performing Audit', 'Performing Audit'),
('Report', 'Report'),
)
audit_phase = models.CharField(max_length=30, blank=True, null=True, choices=audit_phase_choice)
assigned_by = models.CharField(max_length=30, blank=True, null=True)
assigned_to = models.ManyToManyField(User, blank=True)
date_assigned = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True)
status = models.CharField(max_length=30, blank=True, null=True)
completed = models.BooleanField('Task Completed', default=False)
date_completed = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True)
start_date = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True)
due_date = models.DateField(auto_now_add=False, auto_now=False, blank=True, null=True)
comment = models.TextField('comments', max_length=3000, default='', blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, blank=True)
def __unicode__(self):
return self.task_title
def get_absolute_url(self):
return reverse("taskmis:user_task_edit", kwargs={"id": self.id})
Here is the form.py content
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ['task_title',
'unit',
'assigned_to',
'start_date',
'due_date',
'comment']
Here is the view.py content:
def user_task_entry(request):
title = 'Assign Task'
form = TaskForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.assigned_by = request.user
instance.save()
return redirect('taskmis:user_task_list')
context = {
"title": title,
"form": form,
}
return render(request, "task_entry.html",context)
You need to call save_m2m() manually because you set the commit=False when you call the save method
Django Ref
To work around this problem, every time you save a form using
commit=False, Django adds a save_m2m() method to your ModelForm
subclass. After you’ve manually saved the instance produced by the
form, you can invoke save_m2m() to save the many-to-many form data.
For example:

Django. How to write a filter for the current user?

The listings application has a Listing table:
class Listing(models.Model):
realtor = models.ForeignKey(Realtor, on_delete=models.CASCADE, verbose_name='Риэлтор')
region = models.CharField(default="Чуйская", max_length=100, verbose_name='Область')
city = models.CharField(default="Бишкек", max_length=100, verbose_name='Город')
district = models.CharField(blank=True, max_length=100, verbose_name='Район')
title = models.CharField(max_length=200, verbose_name='Заголовок')
address = models.CharField(blank=True, max_length=200, verbose_name='Адрес')
description = models.TextField(blank=True, verbose_name='Описание')
stage = models.IntegerField(blank=True, verbose_name='Этажность')
rooms = models.IntegerField(blank=True, verbose_name='Количество комнат')
garage = models.IntegerField(default=0, blank=True, verbose_name='Гараж')
sqmt = models.IntegerField(blank=True, verbose_name='Площадь')
price = models.IntegerField(blank=True, verbose_name='Цена')
photo_main = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Основное фото')
photo_1 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 1')
photo_2 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 2')
photo_3 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 3')
photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 4')
photo_5 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 5')
photo_6 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, verbose_name='Фото 6')
is_published = models.BooleanField(default=True, verbose_name='Публично')
list_date = models.DateTimeField(default=datetime.now, blank=True, verbose_name='Дата публикации')
def __str__(self):
return self.title
class Meta:
verbose_name = 'Объявление'
verbose_name_plural = 'Объявления'
In the realtors application there is a Realtor model:
class Realtor(models.Model):
user_name = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='Пользователь', related_name='realtor')
name = models.CharField(max_length=20, verbose_name='Имя')
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото')
description = models.TextField(blank=True, verbose_name='Описание')
phone = models.CharField(max_length=20, verbose_name='Телефон')
email = models.CharField(max_length=50, verbose_name='Email')
is_mvp = models.BooleanField(default=False, verbose_name='Реэлтор месяца')
hire_date = models.DateTimeField(default=datetime.now, blank=True, verbose_name='Дата приёма на работу')
def __str__(self):
return self.name
class Meta:
verbose_name = 'Риэлтор'
verbose_name_plural = 'Риэлторы'
In the accounts application, there is a function that in the personal account should only display ads of the current user when he is in the system:
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from listings.models import Listing
from realtors.models import Realtor
def dashboard(request):
listings = Listing.objects.order_by('-list_date').filter(user_name=request.user)
paginator = Paginator(listings, 6)
page = request.GET.get('page')
paged_listings = paginator.get_page(page)
context = {
'listings': paged_listings
}
return render(request, 'accounts/dashboard.html', context
)
How to correctly register this filter so that everything works so that the current user’s ads are displayed:
listings = Listing.objects.order_by('-list_date').filter(user_name=request.user)
At the moment, this error:
Cannot resolve keyword 'user_name' into field. Choices are: address, city, description, district, garage, id, is_published, list_date, photo_1, photo_2, photo_3, photo_4, photo_5, photo_6, photo_main, price, realtor, realtor_id, region, rooms, sqmt, stage, title
Who is not difficult, please help. Thank you in advance.
Since there's no user_name field in Listing, it's an error to try and filter on that.
Instead, you presumably are trying to filter on the realtor, which can done with a lookup that spans relationships:
listings = Listing.objects.order_by('-list_date').filter(realtor__user_name=request.user)
user_name is a field on the Realtor model, not the Listing. Those two models are connected by a ForeignKey, so you need to traverse that relationship using the double-underscore syntax.
Listing.objects.order_by('-list_date').filter(realtor__user_name=request.user)
Note though that user_name is a very odd name for that field; it's not the name, it's the User object itself. It should be called just user.