I have two models as follows :
class FlightSchedule(models.Model):
tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
flight_number = models.CharField(max_length=30, null=False, blank=False)
flight_group_code = models.ForeignKey(FlightGroup, null=False, blank=False)
origin_port_code = models.ForeignKey(Port, null=False, related_name="Origin", blank=False)
destination_port_code = models.ForeignKey(Port, null=False, related_name="Destination", blank=False)
flight_departure_time = models.TimeField()
start_date = models.DateField()
end_date = models.DateField()
def __unicode__(self):
return u'%s' % self.flight_number
class Meta:
verbose_name_plural = "flights Schedule"
class PosFlightSchedule(models.Model):
tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
pos_flight_number = models.ForeignKey(FlightSchedule, max_length=30, null=False, blank=False,
related_name='pos_flight_number')
pos_flight_departure_time = models.ForeignKey(FlightSchedule, max_length=30,
related_name='pos_flight_departure_time')
pos_route_id = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_route_id')
pos_flight_date = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_flight_date')
pax_count = models.IntegerField(null=True)
def __unicode__(self):
return u'%s' % self.pos_flight_number
class Meta:
verbose_name_plural = "Flights Schedule"
For the pos_flight_departure_time , I need the choices from flight_departure_time from the FlightSchedule class. But I get the flight_number values in the drop down. What do I have to change, to get the flight_departure_time values? The classes are from different apps in a single django project. So they have two admin files.
No you don't actually need that. You need only one foreign key in your second model to FlightScheduleDetail and you need just one foreign key to FlightSchedule
class PosFlightSchedule(models.Model):
tail_number = models.ForeignKey(TailNumber, null=False, blank=False)
flight = models.ForeignKey(FlightSchedule, null=False, blank=False,related_name='pos_flight_number')
related_name='pos_flight_departure_time')
pos_route_id = models.ForeignKey(FlightScheduleDetail, null=False, blank=False, related_name='pos_route_id')
pax_count = models.IntegerField(null=True)
def __unicode__(self):
return u'%s' % self.pos_flight_number
class Meta:
verbose_name_plural = "Flights Schedule"
Then all the fields declared in the first model automatically become available to PosFlightSchedule
So for example you can do
p = PosFlightSchedule.objects.all()[0]
print (p.flight.flight_number)
print (p.flight.pos_flight_departure_time)
etc.
This is the correct way to do it.
You may solve this by defining model form, and by not changing to models.py
class PosFlightScheduleForm(forms.ModelForm):
pos_flight_departure_time = forms.ChoiceField(label="Pos Department Time",
choices=[(i.pk, i.flight_departure_time) for i in FlightSchedule.objects.all()],
required=True)
def __init__(self, *args, **kwargs):
super(PosFlightScheduleForm, self).__init__(*args, **kwargs)
self.fields['pos_flight_departure_time'] = forms.ChoiceField(label="Pos Department Time",
choices=[(i.pk, i.flight_departure_time) for i in FlightSchedule.objects.all()],
required=False)
class Meta:
model = PosFlightSchedule
fields = (
"tail_number", 'pos_flight_departure_time',)
In view.py You may use this form
def add_view(self, request):
form = PosFlightScheduleForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('/postflights')
context = {
'form': form,
}
return render(request, 'path/form.html', context)
Related
Hi i'm using ModelFieldChoice to set the foreign key from Provider in the model "Article" (Article belongs to Provider). The select in the template is displayed correctly with all the providers from the database, but when i try to post the form, it throws an error that the select value is required even if i'm passing it. Also i seted values for the article in the database, and when i tried to edit it, all the fields in the form are populated with the correct data except for the select.
These are my models, i would appreciate the help, thanks! Sorry if i'm doing something wrong, this is my first time posting in stackoverflow.
Article.py Model
class Article(models.Model):
codigo = models.CharField(max_length=100, verbose_name='Codigo')
proveedor = models.ForeignKey(Provider, on_delete=models.CASCADE)
descripcion = models.CharField(max_length=200, verbose_name='Descripcion',null=False, blank=True)
marca = models.CharField(max_length=100, verbose_name='Marca',null=True, blank=True)
rubro = models.CharField(max_length=100, verbose_name='Rubro',null=True, blank=True)
nota = models.TextField(verbose_name='Nota',null=True)
costo = models.CharField(max_length=50, verbose_name='Costo',null=False, blank=True)
created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación",null=True, blank=True)
updated = models.DateTimeField(auto_now=True, verbose_name="Fecha de edición",null=True, blank=True)
class Meta:
verbose_name = "articulo"
verbose_name_plural = "articulos"
ordering = ['-descripcion']
def __str__(self):
return self.descripcion
Provider.py Model
class Provider(models.Model):
razon_social = models.CharField(max_length=100, verbose_name='Razón Social', unique=True)
direccion = models.CharField(max_length=100, verbose_name='Dirección', blank=True, null=True)
localidad = models.CharField(max_length=100, verbose_name='Localidad', blank=True, null=True)
provincia = models.CharField(max_length=100, verbose_name='Provincia', blank=True, null=True)
telefono = models.CharField(max_length=100, verbose_name='Teléfono', blank=True, null=True)
mail = models.CharField(max_length=100, verbose_name='Email', blank=True, null=True)
web = models.CharField(max_length=100, verbose_name='Sitio Web', blank=True, null=True)
created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación", null=True)
updated = models.DateTimeField(auto_now=True, verbose_name="Fecha de edición", null=True)
class Meta:
verbose_name = "proveedor"
verbose_name_plural = "proveedores"
ordering = ['-razon_social']
def __str__(self):
return self.razon_social
form.py (ArticleCreate)
class ArticleCreate(forms.ModelForm):
proveedor_id = forms.ModelChoiceField(queryset=Provider.objects.none(), empty_label="Elegir un proveedor")
class Meta:
model = Article
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ArticleCreate, self).__init__(*args, **kwargs)
self.fields['proveedor_id'].queryset = Provider.objects.all()
views.py
def add_article(request):
if request.method == 'POST':
create = ArticleCreate(request.POST)
print(request.POST['proveedor_id'])
if create.is_valid():
create.save()
return redirect('/dashboard/articles/?add=success')
else:
print(create.errors)
return redirect('/dashboard/articles/?error=True')
else:
return render(request, "article/add_edit_article.html", {'editMode': False,'form': ArticleCreate})
In views.py when i print 'proveedor_id' the value is correctly displayed in console but then the "is_valid()" fails and it prints the error "<ul class="errorlist"><li>proveedor<ul class="errorlist"><li>Este campo es obligatorio.</li></ul></li></ul>" (obligatory field, as if i'm not passing it)
First, simplify your ArticleCreate serializer to be like this:
class ArticleCreate(forms.ModelForm):
class Meta:
model = Article
Then in the request pass proveedor field, not proveedor_id. In Django/DRF you should pass association IDs using "{{association_name}}": id pattern, not "{{association_name}}_id": id
Sou you can simplify your view as well:
def add_article(request):
if request.method == 'POST':
create = ArticleCreate(request.POST)
if create.is_valid():
create.save()
...
I'm have been struggling on this for 2 days, really. I want to populate Timesheet form field from Employees model as a select field / dropdown list.
Here are my files and I tried so far.
MODEL.PY
class Employees(models.Model):
# MONTHLY = 'MONTHLY'
# SEMIMONTHLY = 'SEMIMONTHLY'
# BIWKEEKLY = 'BIWKEEKLY'
# WEEKLY = 'WEEKLY'
# DAILY = 'DAILY'
PAY_PERIODS = [
('Monthly', 'Monthly'),
('Bi-weekly', 'Bi-weekly'),
('Weekly', 'Weekly'),
('Daily', 'Daily'),
]
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
is_active = models.BooleanField(default=True, verbose_name='Employee is actives')
first_name = models.CharField(max_length=50, verbose_name='First Name.', null=True, blank=False)
middle_name = models.CharField(max_length=50, verbose_name='Middle Name or Initials.', null=True, blank=True)
last_name = models.CharField(max_length=50, verbose_name='Last Name.', null=True, blank=False)
full_name = models.CharField(max_length=50, null=True, blank=True)
phone = PhoneField(blank=True, null=True)
email = models.EmailField(max_length=150, blank=True, null=True)
state = USStateField(null=True, blank=True)
street_address = models.CharField(max_length=150, blank=True, null=True, verbose_name='Street Address.')
zip_code = models.CharField(max_length=50, blank=True, null=True, verbose_name='Zip Code.')
hourly_rate = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
pay_frequency = models.CharField(max_length=100, choices=PAY_PERIODS, blank=True)
hire_date = models.TimeField(auto_now_add=True)
def __str__(self):
return self.full_name
def save( self, *args, **kwargs ):
self.full_name = f'{self.first_name} {self.middle_name} {self.last_name}'
super().save( *args, **kwargs )
class Timesheet(models.Model):
"""A timesheet is used to collet the clock-ins/outs for a particular day
"""
employer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
full_name = models.ForeignKey(Employees, on_delete=models.CASCADE, null=True, blank=False, verbose_name='Select YOUR Name')
start_date = models.DateField(auto_now_add=True, null=True)
end_date = models.DateField(null=True, blank=False)
time_worked = models.DateField(null=True, blank=False)
def __str__(self):
return self.full_name
VIEWS.PY # I tried both function and class based views
class TimesheetView(CreateView):
model = Timesheet
fields = ('full_name', )
# form_class = TimesheetFrom
# queryset = Employees.objects.filter()
# print(queryset)
template_name = 'users/timesheet.html'
success_url = reverse_lazy('timesheet')
#login_required
def timesheet_view(request):
if request.method == 'POST':
form = TimesheetFrom(request.POST)
if form.is_valid():
emp = form.save(commit=False)
emp.user_id = request.user.pk
emp.save()
return redirect('dashboard')
else:
form = TimesheetFrom()
context = {
'form': TimesheetFrom(),
}
return render(request, 'users/timesheet.html', context)
FORM.PY
class TimesheetFrom(forms.Form):
class Meta:
model = Timesheet
fields = '__all__'
exclude = ('employer', )
#This is the current state of the form but I did tried many approaches.
I did search extensively here (Stackoverflow) but no use case for me. Any help will be greatly appreciated with a cup of coffee.
I have this Model:
class Complaint(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
name = models.CharField(max_length=255, unique=True)
definition = models.TextField(blank=False, default="")
is_violent = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Meta:
ordering = ['name']
def get_absolute_url(self):
return reverse('complaint-details', kwargs={'pk': self.pk})
class Service(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
name = models.CharField(max_length=255, unique=True)
definition = models.TextField(blank=True, default="")
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('service-details', kwargs={'pk': self.pk})
class Location(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
location_name = models.CharField(max_length=255, unique=True)
loc_lat = models.DecimalField(max_digits=9, decimal_places=6)
loc_long = models.DecimalField(max_digits=9, decimal_places=6)
pop = models.PositiveIntegerField(default=500)
is_AOR = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.location_name
class Blotter(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)#default=timezone.now().date()
date = models.DateField(blank=True)
time = models.TimeField(blank=True)
entry_number = models.CharField(max_length=255, unique=True,validators=[RegexValidator(r'^\d{1,255}$')])
complaints = models.ForeignKey(Complaint, on_delete=models.CASCADE, null=True, blank=True)
service = models.ForeignKey(Service, on_delete=models.CASCADE, null=True, blank=True)
information = models.TextField(blank=False, default="")
location = models.ForeignKey(Location, on_delete=models.CASCADE, null=True, blank=True)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ("date_created",)
def __str__(self):
return (self.entry_number)
def get_absolute_url(self):
return reverse('details-blotter', kwargs={'pk': self.pk})
And I have this serializer:
class APILocationListSerializer(serializers.Serializer):
address = serializers.CharField()
latitude = serializers.DecimalField(max_digits=9, decimal_places=5)
longitude = serializers.DecimalField(max_digits=9, decimal_places=5)
population= serializers.IntegerField()
crime_count=serializers.IntegerField()
crime_rate=serializers.DecimalField(max_digits=4, decimal_places=3)
is_aor = serializers.BooleanField()
class Meta:
model = Blotter
fields= [
'address',
'latitude',
'longitude',
'population',
'crime_count',
'crime_rate'
'is_aor',
]
def to_representation(self, value):
context = {
value['address']:
{
'coordinates':[value['latitude'],value['longitude']],
'Population': value['population'],
'Crime-Count': value['crime_count'],
'Crime-Rate': value['crime_rate'],
'Area-Of-Responsibility': value['is_aor'],
}
}
return context
And ListApiView:
class APILocationList(generics.ListAPIView):
serializer_class = APILocationListSerializer
def get_queryset(self):
q=Blotter.objects.values('location__location_name').annotate(
address=F('location__location_name'),
latitude=F('location__loc_lat'),
longitude=F('location__loc_long'),
population=F('location__pop'),
crime_count=Count('complaints', filter=Q(complaints__is_active=True) and Q(complaints__isnull=False)),
crime_rate=(Cast(F('crime_count'), FloatField())/Cast(F('population'), FloatField()))*100000,
is_aor=F('location__is_AOR')
)
q1 = q.filter(location__is_AOR=True).order_by('address')
query_search = self.request.GET.get("q")
if query_search:
q1 = q.filter(Q(location__is_AOR=True) and Q(location__location_name__icontains=query_search)).order_by('address')
return q1
I'm new to django and DRF. I want to achieve a result like this in my API Not Achieved
but this is the result that i've achieved so far Achieved
As you can see in the picture, I want to count the crime trend (highest count of a crime and the crime itself) in every location.
My questions are:
Is this even achievable/possible to get these results using just one query?
If yes, how?
If no, is there any other way to achieve these kind of results?
Thank you in advance!
I can be able to add the first data entry but after that editing the existing data or adding the new data causes MultiValueDictKeyError at /admin/api/digitalpost/9b763eae-cb8b-4473-af5d-5d4d91323ae1/change/
"u'contentlist_set-0-basemodel_ptr'".
Models.py
class BaseModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
version = models.FloatField(default=1.0)
created_at = models.DateTimeField(auto_now_add=True)
def image_tag(self):
self.url = 'http://127.0.0.1:8000/' + self.picture.name
return u'<img src="%s" />' % self.picture.url
image_tag.short_description = 'Thumbnail'
image_tag.allow_tags = True
class Client(BaseModel):
parent = models.ForeignKey('self',on_delete=models.SET_NULL, blank=True, null=True, related_name='brands')
name = models.CharField(max_length=120, unique=True)
picture = models.ImageField(upload_to="static/images/digital")
list_display = ('name','parent',)
description = models.CharField(max_length=250)
def __unicode__(self):
if self.parent:
return "{} {}".format(self.parent.name, self.name)
else:
return self.name
def parent_brand(self):
return str(self)
parent_brand.short_description = 'NAME'
class Meta:
ordering = ['parent__name','name']
class Category(BaseModel):
title = models.CharField(max_length=64, unique=64)
description = models.CharField(max_length=256, null=True, blank=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name_plural = "categories"
class DigitalPost(BaseModel):
title = models.CharField(max_length=100)
brand = models.ForeignKey(Client, on_delete=models.SET_NULL, blank=True, null=True, )
launch_date = models.DateField(blank=True, null=True)
order = models.IntegerField()
def __unicode__(self):
return self.title
class Meta:
ordering = ['order']
class ContentList(BaseModel):
title = models.CharField(max_length=100)
description = models.CharField(max_length=256, null=True, blank=True)
picture = models.ImageField(upload_to="static/images/digital", blank=True)
post = models.ForeignKey(DigitalPost, on_delete=models.SET_NULL, null=True, blank=True)
# post_category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
admin.py
class ContentListForm(forms.ModelForm):
class Meta:
model = models.ContentList
fields = '__all__'
class ContentListInline(admin.TabularInline):
model = models.ContentList
form = ContentListForm
fk_name = 'post'
exclude = ('id', 'version')
class DigitalPostForm(forms.ModelForm):
class Meta:
model = models.DigitalPost
fields = '__all__'
#admin.register(models.DigitalPost)
class DigitalPostAdmin(ActiveStaffPermittedModel):
inlines = [
ContentListInline,
]
form = DigitalPostForm
actions = ['delete_selected']
exclude = ('id', 'version',)
readonly_fields = ('created_at',)
def delete_selected(self, request, obj):
for o in obj.all():
self.delete_one(request, o)
delete_selected.short_description = "Delete selected Posts"
I have a Django 'add business' view which adds a new business with an inline 'business_contact' form.
The form works fine, but I'm wondering how to write up the unit test - specifically, the 'postdata' to send to self.client.post(settings.BUSINESS_ADD_URL, postdata)
I've inspected the fields in my browser and tried adding post data with corresponding names, but I still get a 'ManagementForm data is missing or has been tampered with' error when run.
Anyone know of any resources for figuring out how to post inline data?
Relevant models, views & forms below if it helps. Lotsa thanks.
MODEL:
class Contact(models.Model):
""" Contact details for the representatives of each business """
first_name = models.CharField(max_length=200)
surname = models.CharField(max_length=200)
business = models.ForeignKey('Business')
slug = models.SlugField(max_length=150, unique=True, help_text=settings.SLUG_HELPER_TEXT)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
phone = models.CharField(max_length=100, null=True, blank=True)
mobile_phone = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
deleted = models.BooleanField(default=False)
class Meta:
db_table='business_contact'
def __unicode__(self):
return '%s %s' % (self.first_name, self.surname)
#models.permalink
def get_absolute_url(self):
return('business_contact', (), {'contact_slug': self.slug })
class Business(models.Model):
""" The business clients who you are selling products/services to """
business = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=100, unique=True, help_text=settings.SLUG_HELPER_TEXT)
description = models.TextField(null=True, blank=True)
primary_contact = models.ForeignKey('Contact', null=True, blank=True, related_name='primary_contact')
business_type = models.ForeignKey('BusinessType')
deleted = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
address_1 = models.CharField(max_length=255, null=True, blank=True)
address_2 = models.CharField(max_length=255, null=True, blank=True)
suburb = models.CharField(max_length=255, null=True, blank=True)
city = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=40, null=True, blank=True)
website = models.URLField(null=True, blank=True)
class Meta:
db_table = 'business'
def __unicode__(self):
return self.business
def get_absolute_url(self):
return '%s%s/' % (settings.BUSINESS_URL, self.slug)
VIEWS:
def business_add(request):
template_name = 'business/business_add.html'
if request.method == 'POST':
form = AddBusinessForm(request.POST)
if form.is_valid():
business = form.save(commit=False)
contact_formset = AddBusinessFormSet(request.POST, instance=business)
if contact_formset.is_valid():
business.save()
contact_formset.save()
contact = Contact.objects.get(id=business.id)
business.primary_contact = contact
business.save()
#return HttpResponse(help(contact))
#business.primary = contact.id
return HttpResponseRedirect(settings.BUSINESS_URL)
else:
contact_formset = AddBusinessFormSet(request.POST)
else:
form = AddBusinessForm()
contact_formset = AddBusinessFormSet(instance=Business())
return render_to_response(
template_name,
{
'form': form,
'contact_formset': contact_formset,
},
context_instance=RequestContext(request)
)
FORMS:
class AddBusinessForm(ModelForm):
class Meta:
model = Business
exclude = ['deleted','primary_contact',]
class ContactForm(ModelForm):
class Meta:
model = Contact
exclude = ['deleted',]
AddBusinessFormSet = inlineformset_factory(Business,
Contact,
can_delete=False,
extra=1,
form=AddBusinessForm,
)
The problem is you have not included the management form in your data. You need to include form-TOTAL_FORMS (total number of forms in the formset, default is 2), form-INITIAL_FORMS (the initial number of forms in the formset, default is 0) and form-MAX_NUM_FORMS (the maximum number of forms in the formset, default is '').
See the Formset documentation for more information on the management form.