Django permission row table to a determinate user - django

i'm asking a questions about permissions, i have 2 table, AnagraficaCliente and Tracking with relation 1 to many, autentichate of user is default built in with a django.contrib.auth.urls.
I searched many forum and site but i d ont understand how set permission on row for determinate users. For example:
My site is a web track to show shipped items, if i search a tracking for a user it worked, but all tracking are visible (for all users), i want that only the tracking that belongs to user show to him.
I think that i use model user from
django.contrib.auth.models import User
i don't know how work with my code.
Thanks at all.
models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class AnagraficaCliente(models.Model):
codice_cliente = models.CharField(max_length=20, primary_key=True, null=False, unique=True)
ragione_sociale = models.CharField(max_length=80)
#ragione_sociale_dest = models.CharField(max_length=40)
nome = models.CharField(max_length=40, blank=True)
cognome = models.CharField(max_length=20, blank=True)
#ragione_sociale = models.CharField(max_length=20)
indirizzo = models.TextField(blank=True)
cap = models.CharField(max_length=5, blank=True)
piva = models.CharField(max_length=20, blank=True)
vatnumber = models.CharField(max_length=20, blank=True)
#ragione_sociale_dest = models.CharField(max_length=40)
#indirizzo_dest = models.TextField(null=True)
def __str__(self):
#return self.ragione_sociale + " " + self.codice_cliente
#return self.ragione_sociale_dest + " - " + self.indirizzo_dest + " - " + self.codice_cliente
return self.codice_cliente + " - " + self.ragione_sociale
class Meta:
verbose_name = "AnagraficaCliente"
verbose_name_plural = "AnagraficaClienti"
class Tracking(models.Model):
track = models.CharField(max_length=11, null=False, unique=True, primary_key=True)
indirizzo_dest = models.TextField(null=False)
passaggio1 = models.CharField(max_length=50, blank=True)
data1 = models.DateField(blank=True, null=True)
passaggio2 = models.CharField(max_length=50, blank=True)
data2 = models.DateField(blank=True, null=True)
passaggio3 = models.CharField(max_length=50, blank=True)
data3 = models.DateField(blank=True, null=True)
passaggio4 = models.CharField(max_length=50, blank=True)
data4 = models.DateField(blank=True, null=True)
passaggio5 = models.CharField(max_length=50, blank=True)
data5 = models.DateField(blank=True, null=True)
consegna = (
('C', 'Consegnato'),
('N', 'Non consegnato'),
)
consegnato = models.CharField(
max_length=1, choices=consegna, blank=True, null=True)
#consegnato = models.BooleanField(blank=True)
#esito = models.CharField(max_length=10, blank=True)
flag = models.CharField(max_length=2, blank=True)
AnagraficaCliente = models.ForeignKey(AnagraficaCliente, on_delete=models.CASCADE, related_name='trackings')
def __str__(self):
return self.track
class Meta:
verbose_name = "Tracking"
verbose_name_plural = "Trackings"
admin.py
from django.contrib import admin
from .models import AnagraficaCliente, Tracking
from import_export.admin import ImportExportModelAdmin
#from import_export.admin import ImportExportActionModelAdmin
from import_export import resources
# Register your models here.
class ClientResource(resources.ModelResource):
class Meta:
model = AnagraficaCliente
skip_unchanged = True
report_skipped = True
#fields = ('id','codice_cliente','ragione_sociale','nome','cognome','ragione_sociale','indirizzo','cap','piva','vatnumber')
import_id_fields = ['codice_cliente']
#admin.register(AnagraficaCliente)#Decoratore per mostrare in admin anagraficacliente
class SearchCodice(admin.ModelAdmin):
search_fields = ('codice_cliente', 'ragione_sociale')#Ricerca in admin
list_display = ('codice_cliente','ragione_sociale','indirizzo')#Elenco nomi campo nelle tabelle
class ClientAdmin(ImportExportModelAdmin):
resource_class = ClientResource #Classe per import export csv punta alla classe ClientResource
class ClientResource(resources.ModelResource):
class Meta:
model = Tracking
skip_unchanged = True
report_skipped = True
#fields = ('id','codice_cliente','ragione_sociale','nome','cognome','ragione_sociale','indirizzo','cap','piva','vatnumber')
import_id_fields = ['track']
#admin.register(Tracking)
class SearchTrack(admin.ModelAdmin):
search_fields = ('track', 'consegnato')
list_display = ('track','indirizzo_dest','consegnato')

Ok, i solved in this way:
in models i have add a new field that will contain the exact name of user (see the comment):
user = models.CharField(max_length=20, blank=True)
in views in query objects i change this line:
def tracking_views(request):
query = request.GET.get('q', None)
context = {}
#query_anag = AnagraficaCliente.objects.all()
if query and request.method == 'GET':
#results = Tracking.objects.filter(track=query)#Old line, see next line
results = Tracking.objects.filter(track=query, user=request.user) #Line that
changed
print (type(results))
if results.exists():
context.update({'results': results})
print(context)
else:
return render(request,'tracking_not_found.html',context)
# return HttpResponse("<h1>post creato con successo!</h1>")
return render(request,'tracking.html',context)
So when user is authenticated only the query with number of tracking that belongs to a user will be showed, (of course in every record need to mapped the row of tacking to a new field "user")

Related

How to view value of related foreign key in Django from multiple models

I have the following models in my Django project from different apps
Student App Model
from django.db import models
import batch.models
import course.models
class Student(models.Model):
ACTIVE = 'Active'
DROPPED = 'Dropped'
TRANSFERRED = 'Transferred'
INACTIVE = 'Inactive'
studentStatus = [
(ACTIVE, 'atv'),
(DROPPED, 'drp'),
(TRANSFERRED, 'trf'),
(INACTIVE, 'inv'),
]
first_name = models.CharField('First Name', max_length=30)
last_name = models.CharField('Last Name', max_length=30)
student_batch = models.ManyToManyField(batch.models.Batch,related_name='batch')
contact_no = models.CharField('Contact No', max_length=20, null=True, blank=True)
email_address = models.EmailField('Student Email', null=True, blank=True)
student_status = models.CharField('Student Status', max_length=20, choices=studentStatus,
default=ACTIVE)
student_remark = models.CharField('Student Remark', max_length=255, null=True, blank=True)
student_course = models.ManyToManyField(course.models.Course,related_name='course')
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
Batch App Model
from django.db import models
from datetime import date, timezone
import course.models
import trainer.models
from django.contrib.auth.models import User
class Batch(models.Model):
ACTIVE = 'Active'
HOLD = 'Hold'
SCHEDULED = 'Scheduled'
CANCELED = 'Canceled'
TRANSFERRED = 'Transferred'
batchStatus = [
(ACTIVE, 'act'),
(HOLD, 'hld'),
(SCHEDULED, 'scd'),
(CANCELED, 'cld'),
(TRANSFERRED, 'trd'),
]
batch_course = models.ForeignKey(course.models.Course, on_delete=models.SET_NULL, blank=True, null=True)
batch_trainer = models.ForeignKey(trainer.models.Trainer, on_delete=models.SET_NULL, blank=True, null=True)
batch_time = models.TimeField('Batch Time', blank=True, null=True)
batch_start_date = models.DateField('Batch Start Date', default=date.today)
created_by = models.ManyToManyRel('Batch Created By', to=User)
batch_status = models.CharField('Batch Status', choices=batchStatus, default=ACTIVE, max_length=20)
created_on=models.DateTimeField(auto_now_add=True)
updated_on=models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.batch_course} | {self.batch_time} | {self.batch_start_date}"
Course App Model
from django.db import models
from django.core import validators
class Course(models.Model):
name = models.CharField('Course Name', max_length=120)
duration = models.PositiveIntegerField('Course Duration')
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
want output in student view which shows
all students data with their associated course and batch
eg:
Student Name | Course Name | Batch Name
when i tried it with foreign key, i got all result with primary key of foreign table, i am not sure how to get name associated with those key as i don't have single result so i can compare it with foreign key.
student_detail = Student.objects.all().values("first_name", "student_course__name", "student_batch__batch_time").prefetch_related("student_batch", "student_course")
As in your Course model, I didn't find any name field, so I put batch_time instead of name for your understanding.

Django Import Export, Filter ForeignKey objects connected to users

I'm building an import excel files system for every leads whit an import-export library. On the Website, each user must be able to import his leads and make sure that they are viewed only by him. In all other cases, I filtered the "organisation" field linked to a UserProfile model through the views.py. But now I don't know how to filter the field organisation for a specific user. At the moment I can import the excel files from the template but leave the organisation field blank. Help me please I'm desperate
Models.py
class Lead(models.Model):
nome = models.CharField(max_length=20)
cognome = models.CharField(max_length=20)
luogo=models.CharField(max_length=50, blank=True, null=True, choices=region_list)
città=models.CharField(max_length=20)
email = models.EmailField()
phone_number = models.CharField(max_length=20)
description = models.TextField()
agent = models.ForeignKey("Agent", null=True, blank=True, on_delete=models.SET_NULL)
category = models.ForeignKey("Category", related_name="leads", null=True, blank=True, on_delete=models.SET_NULL)
chance=models.ForeignKey("Chance",related_name="chance", null=True, blank=True, on_delete=models.CASCADE)
profile_picture = models.ImageField(null=True, blank=True, upload_to="profile_pictures/")
converted_date = models.DateTimeField(null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE,null=True, blank=True)
objects = LeadManager()
age = models.IntegerField(default=0)
def __str__(self):
return f"{self.nome} {self.cognome}"
class User(AbstractUser):
is_organisor = models.BooleanField(default=True)
is_agent = models.BooleanField(default=False)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.user.username
Views.py
def simple_upload(request):
if request.method == 'POST':
Lead_resource = LeadResource()
dataset = Dataset()
newdoc = request.FILES['myfile']
imported_data = dataset.load(newdoc.read(),format='xlsx')
#print(imported_data)
for data in imported_data:
value = Lead(
data[0],
data[2],#nome
data[3],#cognome
data[5],#luogo
data[7],#città
data[8],#email
data[9],#numero telefono
data[11],#desc
)
value.save()
result = Lead_resource.import_data(dataset, dry_run=True) # Test the data import
if not result.has_errors():
Lead_resource.import_data(dataset,dry_run=False) # Actually import now
return render(request, 'input.html')
Resources.py
class LeadResource(resources.ModelResource):
nome = fields.Field(attribute='nome', column_name='nome')
luogo = fields.Field(attribute='luogo', column_name='regione')
class Meta:
model = Lead
report_skipped=True
admin.py
#admin.register(Lead)
class PersonAdmin(ImportExportModelAdmin):
readonly_fields = ('date_added',)

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.

Django rest framework, result is not returned in retrieveapiview

I am new to django rest framework. I have 2 models, Store and Rate. For this API, you enter store number to find the state. and find the rate in that state. I am able to get the rate and print it in the console. but for some reasons I kept getting no found.
class RateDetailAPIView(RetrieveAPIView):
def get_queryset(self):
storeNumber = str(self.kwargs['store_number'])
store = Store.objects.get(store_number = storeNumber)
rate = Rate.objects.get(state = store.state)
print(rate.proposed_per_store_rate)
return rate
#queryset = self.get_queryset()
lookup_field = 'store_number'
serializer_class = RateSerializer
this is what i get in the console. 1700 is the rate. then I get no found.
1700
Not Found: /api/rates/1910003/
[16/Apr/2018 17:56:07] "GET /api/rates/1910003/ HTTP/1.1" 404 5249
Models:
from django.db import models
class Store(models.Model):
store_number = models.CharField(max_length=50, blank=False, unique=True)
address = models.CharField(max_length=255, blank=False, unique=False)
address2 = models.CharField(max_length=255, blank=True, unique=False)
city = models.CharField(max_length=50, blank=False, unique=False)
state = models.CharField(max_length=10, blank=False, unique=False)
zip_code = models.CharField(max_length=50, blank=True, unique=False)
phone_number = models.CharField(max_length=50, blank=True, unique=False)
store_hours = models.CharField(max_length=255, blank=True, unique=False)
latitude = models.CharField(max_length=50, blank=True, unique=False)
longitude = models.CharField(max_length=50, blank=True, unique=False)
geo_accuracy = models.CharField(max_length=255, blank=True, unique=False)
country = models.CharField(max_length=50, blank=True, unique=False)
country_code = models.CharField(max_length=10, blank=True, unique=False)
county = models.CharField(max_length=50, blank=True, unique=False)
def __str__(self):
return"{}".format(self.store_number)
class Rate(models.Model):
number_of_stores = models.IntegerField()
state = models.CharField(max_length=5, blank=False, unique=False)
proposed_per_store_rate = models.IntegerField()
proposed_prem = models.IntegerField()
def __str__(self):
return "{}".format(self.state + ":" + str(self.proposed_per_store_rate))
Serializers:
from rest_framework import serializers
from .models import Store, StoreRate, Rate
class StoreSerializer(serializers.ModelSerializer):
class Meta:
model = Store
fields = ('id', "store_number", "address", "address2", "city", "state", "zip_code", "phone_number", "store_hours", "latitude", "longitude", "geo_accuracy", "country", "country_code", "county")
class RateSerializer(serializers.ModelSerializer):
class Meta:
model = Rate
fields = ('id', "number_of_stores", "state", "proposed_per_store_rate", "proposed_prem")
URL:
from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns
from .views import (AllStoresAPIView, StoreDetailAPIView, StoreLoadAPIView, StoreRateDetailAPIView, RateDetailAPIView)
urlpatterns = {
url(r'^api/stores/$', AllStoresAPIView.as_view(), name="stores"),
#url(r'^api/stores/load/$', StoreLoadAPIView.as_view(), name="load"),
url(r'^api/stores/(?P<store_number>\d+)/$', StoreDetailAPIView.as_view(), name='detail'),
#url(r'^api/quote/(?P<store_number>\d+)/$', StoreRateDetailAPIView.as_view(), name='quote'),
url(r'^api/rates/(?P<store_number>\d+)/$', RateDetailAPIView.as_view(), name='rate'),
}
urlpatterns = format_suffix_patterns(urlpatterns)
you get_queryset should return queryset not instance, for your case RetrieveAPIView need to override the get_object method, for example:
class RateDetailAPIView(RetrieveAPIView):
queryset = Rate.objects.all()
lookup_field = 'store_number'
serializer_class = RateSerializer
def get_object(self):
# ^^^^^^^^^
storeNumber = str(self.kwargs['store_number'])
store = Store.objects.get(store_number = storeNumber)
rate = Rate.objects.get(state = store.state)
print(rate.proposed_per_store_rate)
return rate
you can read more get_object

How to set Instance of models to make a confirmation form in Django

I need to save the info of these models with foreign keys, so I created a view for Candidato, InfoPersonal and InfoAcademica, and finally I created a confirm view to save Solicitud but that page shows me:
TypeError at /solicitud/confirmacion/2/
'instance' is an invalid keyword argument for this function
My models.
project/apps/solicitud/models.py
class Candidato(models.Model):
nombre = models.CharField(max_length=50)
apellidos = models.CharField(max_length=70)
email = models.EmailField(unique=True)
def __unicode__(self):
return u'{} {}'.format(self.nombre, self.apellidos)
class InfoPersonal(models.Model):
candidato = models.ForeignKey(Candidato, null=False, blank=False, on_delete=models.CASCADE)
sexo = models.CharField(max_length=9, choices=SEXO_CHOICES)
fecha_nacimiento = models.DateField()
curp = models.CharField(max_length=18, unique=True)
pais_origen = models.CharField(max_length=30, default="México")
lugar_nacimiento = models.CharField(max_length=100)
domicilio = models.CharField(max_length=120)
codigo_postal = models.CharField(max_length=5)
telefono = models.CharField(max_length=20)
def __unicode__(self):
return u'{}'.format(self.curp)
class InfoAcademica(models.Model):
persona = models.ForeignKey(Candidato, null=True, blank=True, on_delete=models.CASCADE)
escuela_procedencia = models.CharField(max_length=50)
programa_solicitado = models.CharField(max_length=50, choices=PROGRAMA_SOLICITADO_CHOICES, default=MAS_ADMIN)
titulado = models.CharField(max_length=10, choices=ESTADO_TITULACION_CHOICES, default=YA_TITULADO)
titulacion_creditos = models.CharField(max_length=2, choices= TITULACION_CREDITOS_CHOICES, default=NO)
def __unicode__(self):
return u'{}'.format(self.programa_solicitado)
class Solicitud(models.Model):
candidato = models.ForeignKey(Candidato, null=True, blank=True)
academica = models.ForeignKey(InfoAcademica, null=False, blank=False)
Personal = models.ForeignKey(InfoPersonal, null=False, blank=False)
def __unicode__(self):
return u'Solicitud id: {}'.format(self.id)
My URLS, here I send a pk for every model to link them in Solicitud
# -*- coding: utf-8 -*-
from django.conf.urls import url
import views
app_name = 'solicitud'
urlpatterns = [
url(r'^datos_candidato/$', views.AddDatosCandidato.as_view(), name='datos_candidato'),
url(r'^datos_personales/$', views.AddDatosPersonales.as_view(), name='datos_personales'),
url(r'^datos_academicos/$', views.AddDatosAcademicos.as_view(), name='datos_academicos'),
url(r'^confirmacion/(?P<pk>\d+)/$', views.AddSolicitud.as_view(), name='datos_confirmacion'),
]
and finally my views, Here I don't know how to send the instancen of the 2 models and save it in Solicitud
project/apps/solicitud/views.py
class AddSolicitud(CreateView):
model = Solicitud, InfoPersonal, InfoAcademica
form_class = Solicitud
template_name = 'solicitud/confirmacion_solicitud.html'
You have form_class = Solicitud, but Solicitud is a model not a form.
Also, you can't specify more than one model in the model = line.