Search A between B in ManyToManyField - django

I tried to search a local manager from zipcode A to zipcode B.
For example:
"Manager west" as the regions
zipform | zipto
17000 to 17259
17300 to 19309
19360 to 19419
23920 to 23999
models.py
class Region(models.Model):
zipfrom = models.CharField(u'PLZ von', max_length=50, blank=True)
zipto = models.CharField(u'PLZ bis', max_length=50, blank=True)
class Meta:
verbose_name = u'Region'
verbose_name_plural = u'Regionen'
def __unicode__(self):
return "{0} - {1}".format(self.zipfrom, self.zipto)
class AddPartner(models.Model):
name = models.CharField(u'Name', max_length=50)
regionen = models.ManyToManyField(Region, verbose_name=u'regionen', blank=True)
class Meta:
verbose_name = u'AddPartner'
verbose_name_plural = u'AddPartners'
def __unicode__(self):
return self.name
views.py
from django.shortcuts import redirect, render, render_to_response
from django.template import Template, RequestContext
from partner.models import AddPartner, Region
from django.db.models import Q
def partnerview(request):
partner = AddPartner.objects.all()
region = Region.objects.all()
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
suche = region.filter(Q(zipto=q) | Q(zipform=q)) # despair
else:
return render_to_response('partner.html',{
'partner': partner, 'region': region, },context_instance=RequestContext(request))
return render_to_response('partner.html',{
'partner': partner, 'region': region,'suches': suche, 'query': q
},context_instance=RequestContext(request))
I am a beginner and I have no idea to handle this. The next big question is to get the rigt result "the local manager" in the template.

You can use the pair of __lte/__gte lookups. The next query will find the regions where zipfrom <= q <= zipto:
suche = region.filter(zipfrom__lte=q, zipto__gte=q)
To get the list of managers for found regions use the following query:
managers = AddPartner.objects.distinct().filter(regionen__in=suche)

Related

NOT NULL constraint failed: shipping_ship.user_id Django

So I'm working on a shipping website with the django rest framework. The website brings two to four people together so they can easily ship their goods together at the same time. But I'm facing a major stumbling block on the views where user book a shipping the code is below.
models.py
from django.db import models
from django.contrib import get_user_model
User = get_user_model()
class Container(models.Model):
container_type = models.Charfield(max_length = 30, blank=False, null = False)
max_users = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places =2, default=0, blank=True, null=True)
users = models.ManyToManyField(User)
class Ship(models.Model):
container = models.ForeignKey(Container, related_name='cont', on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name='shipper', on_delete=models.CASCADE)
location = (
('France', 'France'),
)
from_location = models.CharField(max_length=30, choices=location, blank=False, null=False)
to_location = (
('Lagos', 'Lagos'),
('Abuja', 'Abuja'),
('Abeokuta', 'Abeokuta'),
('Osun', 'Osun'),
)
to_location = models.CharField(max_length=30, choices=to_location, blank=False, null=False)
date_leaving = models.DateField(auto_now=False)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0, blank=True, null=True)
def __str__(self):
return self.user
then my serializer.py file
from rest_framework import serializers
from .models import Container, Ship
class ContainerSerializer(serializers.ModelSerializer):
class Meta:
model = Container
fields = '__all__'
class MiniContainerSerializer(serializers.ModelSerializer):
class Meta:
model = Container
fields =['container_type', 'price']
class ShipSerializer(serializers.ModelSerializer):
class Meta:
model = Ship
fields = '__all__'
read_only_fields = ('user', 'price')
class MiniShipSerializer(serializers.ModelSerializer):
class Meta:
model = Ship
fields = ['container', 'from_location', 'to_location']
and now my views.py file which I have issues with
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from rest_framework.generics import ListCreateAPIView, CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView, RetrieveAPIView
from .serializers import ContainerSerializer, MiniContainerSerializer, ShipSerializer, MiniShipSerializer
from rest_framework import permissions, status
from rest_framework.response import Response
from .models import Container, Ship
class ShipAPI(ListCreateAPIView):
serializer_class = ShipSerializer
def get_queryset(self):
user = self.request.user
queryset = Ship.objects.filter(user=user)
return queryset
def Book_shipping(self, request, *args, **kwargs):
user = request.user
container = get_object_or_404(Container, pk=request.data['container'])
if container.users.count() >= container.max_users:
return Response('container already full')# here i'm trying to set limits so the users joining each container won't surpass the max users.
cont = container(users=user)
cont.save()
from_location = (request.data['from_location'])
to_location = (request.data['to_location'])
date_leaving = int(request.data['date_leaving'])
price = container.price / container.max_users
cart = Ship(container=container, user=user, from_location=from_location, to_location=to_location, date_leaving=date_leaving, price=price)
cart.save()
serializer = ShipSerializer(cart)
data ={'message': 'shipping successfully created',
'data':serializer.data}
return Response(data=data, status=status.HTTP_201_CREATED)
and then after testing the endpoint it returns this error:
IntegrityError at /Shipping/Ship/
NOT NULL constraint failed: shipping_ship.user_id
I've tried debugging and looking at it over and over again can someone please help me? Thanks in advance. And yes I've tried deleting migrations and the database.
As your Container model have a ManyToMany relationship with the User model.
So it may not work like cont = container(users=user)
For me it worked like this:
cont = container.users.add(user)
cont.save()

How to set specific conditions in models.py while entering data in admin panel?

room_category = models.ForeignKey(Cat, on_delete=models.CASCADE)
number = models.IntegerField(unique=True)
people = models.IntegerField()
picture = models.ImageField(upload_to = 'room/', null=True, blank=True)
actual_price = models.IntegerField()
offer_price = models.IntegerField()
def __str__(self):
return '%d : %s with People : %d' % (self.number, self.room_category, self.people)
I want to set a condition in offer_price table that offer_price < actual_price. It should show an error while entering data in the admin panel itself.
You can add validation in the .clean(…) method [Django-doc], and add a database constraint with Django's constraint framework:
from django.core.exceptions import ValidationError
from django.db.models import F, Q
class YourModel(models.Model):
# …
actual_price = models.IntegerField()
offer_price = models.IntegerField()
def clean(self, *args, **kwargs):
if self.actual_price <= self.offer_price:
raise ValidationError('offer price should be lower than the actual price')
return super().clean(*args, **kwargs)
class Meta:
constraints = [
models.CheckConstraints(
check=Q(offer_price__lt=F('actual_price')),
name='lower_than_actual_price'
)
]

'FieldFile' object has no attribute 'full_clean'

I've been trying to implement a file size validator in django on a filefield, but I can't really make it work.
Everything works right until I add this validator. After I add it, I can't upload files anymore at all. The error says "File field does not have a full_clean attribute".
views.py
from django.shortcuts import render, get_object_or_404
from .models import Oferta, CV
from django.contrib import messages
from django.core.paginator import Paginator
def incarcarecv(req):
context = {
'title': "Incarcare CV | Best DAVNIC73"
}
if req.method == 'POST':
nume = req.POST['nume']
prenume = req.POST['prenume']
telefon = req.POST['telefon']
email = req.POST['email']
cv = req.FILES['CV']
if(req.user.is_authenticated):
cv_upload = CV(
solicitant=req.user,
nume=nume,
prenume=prenume,
telefon=telefon,
emailContact=email
)
cv_upload.CVFile.full_clean()
cv_upload.CVFile.save(cv.name, cv)
cv_upload.save()
req.user.profile.cvuri.append(cv_upload.id)
req.user.profile.save()
messages.success(req, 'CV depus cu succes!')
else:
messages.error(req, 'Trebuie sa fii logat pentru a depune CV-ul!')
return render(req, "../templates/pagini/incarcare-cv.html", context)
models.py
from django.db import models
from django.contrib.auth.models import User
from .validators import validate_file_size
# Create your models here.
class Oferta(models.Model):
solicitant = models.ForeignKey(User, on_delete=models.CASCADE)
dataSolicitare = models.DateField(auto_now_add=True)
cor = models.CharField(max_length=25)
denumireMeserie = models.CharField(max_length=12)
locuri = models.IntegerField()
agentEconomic = models.CharField(max_length=50)
adresa = models.CharField(max_length=150)
dataExpirare = models.DateField()
experientaSolicitata = models.CharField(max_length=200)
studiiSolicitate = models.CharField(max_length=200)
judet = models.CharField(max_length=20)
localitate = models.CharField(max_length=25)
telefon = models.CharField(max_length=12)
emailContact = models.EmailField(max_length=40)
rezolvata = models.BooleanField(default=False)
def __str__(self):
return self.cor
class CV(models.Model):
solicitant = models.ForeignKey(User, on_delete=models.CASCADE)
dataUploadCV = models.DateField(auto_now_add=True)
nume = models.CharField(max_length=12)
prenume = models.CharField(max_length=12)
telefon = models.CharField(max_length=12)
emailContact = models.EmailField(max_length=40)
CVFile = models.FileField(upload_to='documents/%d/%m/%Y', validators=[validate_file_size])
rezolvata = models.BooleanField(default=False)
def __str__(self):
return self.nume + " " + self.prenume + ": " + str(self.CVFile)
validators.py
from django.core.exceptions import ValidationError
def validate_file_size(value):
filesize=value.size
if filesize > 5000000:
raise ValidationError("Maximum 5MB!")
I just can't seem to get why. Can you help me fix my code?
As far as I know, .full_clean() runs some default django validators + the ones set in the model.
But actually it does not work.
Exception Value:
'FieldFile' object has no attribute 'full_clean'
Can you explain to me why is this happening and how can I make my validator run?
Thanks.
//by the way, someone recommended to change the order of the lines like this -
cv_upload.CVFile.save(cv.name, cv)
cv_upload.CVFile.full_clean()
but it does not work anyway.
As the error says, full_clean() isn't a method of a model field. It's a method of the model itself.
cv_upload.full_clean() works.
But you should just initialise your cv_upload with the file directly:
cv_upload = CV(
solicitant=...,
...,
CVFile=cv)
then you don't have to save the file separately, see the docs.
Also, you're running full_clean() but not catching any exceptions. What happens if validation fails? A ValidationError will be thrown. If you don't catch it, your view will return a HTTP 500 error (it will just crash).
So wrap it in a try ... except clause:
try:
cv_upload.full_clean()
except ValidationError as e:
messages.error(request, e)
else:
cv_upload.save()
messages.success(request, "yeah!")

Dynamically update fields in django

When I create new sesid in session I need all the courses to add to the sesid in Registration model.
I am creating a result management system using django.
What I want to do is to
create a session (it is done)
then automatically, all the courses from course model will be in the
session model ( I don't need to add individually) and then show a
page that enables to add batch to the added courses.
After submission all the students of the corresponding batch will be
added to the course and thus session and redirect to somewhere to enable user to assign each course to a specific teacher
each of the students have several marks fields to cover by the assigned teacher
the result will be calculated and saved in the database after input from a table (better as an imported excel file)
so far, I have made this:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
class Course(models.Model):
cid = models.AutoField(primary_key=True)
cnam = models.CharField(max_length=200)
cidn = models.IntegerField()
cred = models.IntegerField()
def __str__(self):
return 'IT-' + str(self.cidn) + ' - ' + self.cnam
class Student(models.Model):
snam = models.CharField(max_length=200)
sid = models.AutoField(primary_key=True)
sroll = models.IntegerField()
sreg = models.IntegerField()
sbtc = models.IntegerField()
sses = models.CharField(max_length=10)
def __str__(self):
return self.snam
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
full_name = models.CharField(max_length=200, null=True)
umob = models.CharField(max_length=20, blank=True, default='')
ulogo = models.ImageField(upload_to='media', blank=True)
def __str__(self):
return self.user.username
def createprofile(selfsender, **kwargs):
if kwargs['created']:
user_profile = Teacher.objects.creeate(user=kwargs['instance'])
class Session(models.Model):
sesid = models.IntegerField(primary_key=True,verbose_name= ('Session'))
def __str__(self):
return str(self.sesid)
def get_absolute_url(selfself):
return reverse('Dashboard:session')
class Registration(models.Model):
session = models.ForeignKey(Session, on_delete=models.CASCADE)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
# def __str__(self):
# return str(self.session.sesid) + ' - ' + 'IT-' + self.str(course.cidn) + ' - ' + self.course.cnam + ' - ' + self.str(Teacher.user)
class Result(models.Model):
reg = models.ForeignKey(Registration, on_delete=models.CASCADE)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
ct1 = models.FloatField(null=True, blank=True)
ct2 = models.FloatField(null=True, blank=True)
ct3 = models.FloatField(null=True, blank=True)
asn = models.FloatField(null=True, blank=True)
# avg
atd = models.IntegerField(null=True, blank=True)
#total
def __str__(self):
return str(self.reg.session) + ' - ' + 'IT-' + str(self.reg.course.cidn) + ' - ' + self.student.snam
views.py:
from django.urls import reverse_lazy
from django.views import generic
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView
from django.shortcuts import render, redirect
from django_tables2 import RequestConfig
from .tables import *
from .models import *
from .forms import CustomUserChangeForm
class Login(generic.CreateView):
form_class = CustomUserChangeForm
success_url = reverse_lazy('index')
template_name = 'Dashboard/login.html'
class IndexView(ListView):
template_name = 'Dashboard/index.html'
def get_queryset(self):
return Course.objects.all()
def course(request):
table = CourseTable(Course.objects.all())
RequestConfig(request).configure(table)
return render(request, 'Dashboard/course.html', {'table': table})
def teacher(request):
table = TeacherTable(Teacher.objects.all())
RequestConfig(request).configure(table)
return render(request, 'Dashboard/teacher.html', {'table' : table})
def student(request):
table = StudentTable(Student.objects.all())
RequestConfig(request).configure(table)
return render(request, 'Dashboard/student.html', {'table' : table})
def result(request):
table = ResultTable(Result.objects.all())
RequestConfig(request).configure(table)
return render(request, 'Dashboard/result.html', {'table' : table})
class SessionView(CreateView,ListView):
template_name = 'Dashboard/createSession.html'
model = Session
fields = ['sesid']
def get_queryset(self):
return Session.objects.all()
How can I approach to the dynamic update of database?
Based on the explanation in the comment, something like this should do the trick.
For reusability, you could also move the for course... bit to a method on Session, such as add_courses(self, teacher): ...
class SessionView(CreateView, ListView):
template_name = 'Dashboard/createSession.html'
model = Session
queryset = Session.objects.all()
fields = ['sesid']
def form_valid(self, form): # this will be the creation form
instance = form.save() # save the empty session
for course in Course.objects.all():
Registration.objects.create(
session=instance,
course=course,
teacher=self.request.user.teacher, # (Is this correct?)
)
return HttpResponseRedirect(self.get_success_url())

more than 1 foreign key

I have the following models: http://slexy.org/view/s20T8yOiKZ
from mxutils.cms_services import generate_secid
from django.db import models
from django.contrib import admin
from django import forms
class World(models.Model):
title = models.CharField(max_length=150)
secid = models.SlugField(max_length=1000, editable=False)
elements = models.ManyToManyField("Element", related_name='elements', blank=True, null=True)
metadata = models.OneToOneField("Category_metadata", blank=True, null=True)
def save(self):
if not self.pk:
super(World, self).save()
self.secid = generate_secid(self.title, self.pk, World.objects.all())
return super(World, self).save()
def __unicode__(self):
return "%s" % self.title
class Element(models.Model):
parent = models.ForeignKey(World, related_name='element_parent')
world = models.ForeignKey(World, related_name='world', blank=True, null=True)
item = models.ForeignKey("Item", blank=True, null=True)
value = models.DecimalField(default=0, max_digits=5, decimal_places=3)
def save(self):
if self.world and self.item:
return None
elif not self.world and not self.item:
return None
else:
return super(Element, self).save()
def __unicode__(self):
if self.world:
return "%s" % self.world.title
else:
return "%s" % self.item.title
class ElementInline(admin.TabularInline):
model = Element
extra=1
class WorldAdmin(admin.ModelAdmin):
inlines = [ElementInline,]
list_display = ('title',)
ordering = ['title']
search_fields = ('title',)
When I try to click add button for worlds in admin page it shows me the following error:
class 'cms_sample.world_models.Element' has more than 1 ForeignKey to class 'cms_sample.world_models.World'.
I think it's something to do with inline.
What can it be?
Django doesn't know which of the two foreign keys (parent and world) is to be inlined using the ElementInline.
class ElementInline(admin.TabularInline):
model = Element
fk_name = 'parent' #or 'world', as applicable.
extra=1