It is appeared that my value from my form does not insert correctly in my table. Below are my code:-
## my Forms.py ##
class AerialPhotoForm(forms.ModelForm):
class Meta:
model = AerialFoto
fields = ['year_id', 'scale_id', 'index_id', 'location_id', 'size']
## my Views.py ##
if request.method == 'POST':
form = AerialPhotoForm(request.POST)
if form.is_valid():
form.save()
## my Models.py ##
class AerialFoto(models.Model):
AerialFoto_id = models.AutoField(primary_key=True)
index_id = models.ForeignKey(No_index, null=True, blank=True)
scale_id = models.ForeignKey(Scale, null=True, blank=True)
location_id = models.ForeignKey(Location, null=True, blank=True)
year_id = models.ForeignKey(Year, null=True, blank=True)
file_directory = models.CharField(max_length=255)
size = models.DecimalField(max_digits=19, decimal_places=2, blank=True, null=True)
gsd = models.CharField(max_length=7)
And the result that i've got:-
My Admin
To see a verbose expression of an object, you need to define a __unicoide__ (or __str__ if python 3.x) method in your models:
class Location(models.Model):
...
name = models.CharField.....
def __unicode__(self): # or __str__ if python 3
return self.name # assuming you have a name field, you can use any string field.
# You could return any string here to test
# e.g. return 'This is my object'
And the same for No_Index, Scale and Year models.
Related
This is my models.py file
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Book(models.Model):
category_choices =(
#("Undefined","Undefined"),
("Action", "Action"),
("Romance", "Romance"),
("Horror", "Horror"),
("Comedy", "Comedy"),
("Adventure", "Adventure"),
("Dramatic", "Dramatic"),
("Crime","Crime"),
("Fantasy","Fantasy"),
)
name = models.CharField(max_length=100)
author = models.CharField(max_length=100, null=True)
content = models.TextField()
price = models.DecimalField(max_digits=5, decimal_places=2)
image = models.ImageField(upload_to= 'photos/%y/%m/%d', blank = True)
category = models.CharField(
max_length = 20,
choices = category_choices,
#default = 'Undefined'
)
publication_year = models.CharField(max_length=4, null=True)
ISBN = models.CharField(max_length=13, null=True, unique=True)
active = models.BooleanField(default= True)
def __str__(self):
return self.name
class Borrow(models.Model):
name = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
book = models.OneToOneField(Book, null=True, on_delete= models.SET_NULL)
period = models.PositiveIntegerField(default=0)
id = models.IntegerField(primary_key=True)
def __str__(self):
return str(self.book)
and this is my forms.py file
from django import forms
from .models import Borrow
class BorrowForm(forms.ModelForm):
class Meta:
model = Borrow
fields = ('name', 'book', 'period')
and this is the function in my views.py file that renders the form
#login_required
def borrowing(request):
momo = BorrowForm()
if request.method == 'POST':
momo = BorrowForm(request.POST)
if momo.is_valid():
instacne = momo.save(commit=False)
instacne.user = request.user.username
instacne.save()
return redirect('profile')
return render(request, 'books/book.html', {'momo': momo})
The role of this function is to render that form and to save the data that user will enter and automatically assign the username of the current user to the field 'name' in form.
I tried alot of things to get the username of the current user and assign it to the field 'name' but nothing works and that field stays blank.
You're using a models.ForeignKey(User) so that table will store a user id, not a username. I'd call this field user and not name, personally.
Therefore you need to provide a user instance to it like this;
#login_required
def borrowing(request):
initial = {}
if request.user.is_authenticated:
initial.update({'name': request.user})
momo = BorrowForm(initial=initial)
if request.method == 'POST':
momo = BorrowForm(request.POST)
if momo.is_valid():
instance = momo.save(commit=False)
instance.user = request.user
instance.save()
If you wanted to easily get the username for a Borrow instance you could do this;
class Borrow(models.Model):
name = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
book = models.OneToOneField(Book, null=True, on_delete= models.SET_NULL)
period = models.PositiveIntegerField(default=0)
id = models.IntegerField(primary_key=True)
def __str__(self):
return str(self.book)
#property
def username(self):
return self.name.username
If you want the form to offer users by username, you can either have the str method of your user model return username, or create custom choices as a tuple of user ID & username in the form __init__
here is my model.py
class Product(models.Model):
user = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
coinid = models.CharField(max_length=255, unique = True, null=True)
digit = models.CharField(max_length=18, unique = True, null=True)
ctp = models.FloatField(max_length=100, null=True)
transection_id = models.IntegerField(null=True, default=0)
slug = models.SlugField(max_length=250, null=True, blank=True)
date_created = models.DateField(auto_now_add=True, null=True)
when the user fills the form which includes = coinid and ctp.
I want Django to automatically fill Digit(unique) and user(logged in) fields for me when updated to the products table.
here is my form.py
class CreateProduct(ModelForm):
class Meta:
model = Product
fields = ['user','coinid', 'ctp']
exclude = ['user']
views.py
def createProduct(request):
user_id = request.user.customer
form = CreateProduct(instance=user_id)
if request.method == 'POST':
form = CreateProduct(request.POST)
if form.is_valid():
form.save()
return redirect('/products/')
context = {'form': form}
return render(request, 'accounts/newcoin.html', context)
Also, I want to validate the product's ctp value whenever a user types in the unique digit to another form.
you can override the save method on the Product model to achieve what you want
example: models.py
import uuid
class Product(models.Model):
user = models.ForeignKey(User, null=True,
blank=True,on_delete=models.CASCADE)
coinid = models.CharField(max_length=255, unique = True, null=True)
digit = models.CharField(max_length=18, unique = True, null=True)
ctp = models.FloatField(max_length=100, null=True)
transection_id = models.IntegerField(null=True, default=0)
slug = models.SlugField(max_length=250, null=True, blank=True)
date_created = models.DateField(auto_now_add=True, null=True)
def save(self, *awags, **kwargs):
# if coinid and ctp is not none
# save a uuid in the digit field
if self.coinid and self.ctp:
self.digit = str(uuid.uuid4())
# Your code to change the user model here
# exmaple to change user name
user = User.objects.get(id = self.user.id)
user.username = "Stackoverflow user"
user.save()
super().save(*awags, **kwargs)
You can check the Django docs for reference to override Save method
For creating unique IDs you can use the python uuid module
import uuid
unique_id = str(uuid.uuid4())
You can also use uuid.uuid1() however the docs recommends uuid4 for a random unique string
You can check the docs for uuid here
I have 2 models, Item and OnHand. Item represents the product, like a USB Keyboard, while OnHand represents an actual USB Keyboard.
class Item(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=100)
manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True, on_delete=models.SET_NULL)
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
vendor = models.ForeignKey(Vendor, blank=True, null=True, on_delete=models.SET_NULL)
vendor_sku = models.CharField(max_length=80, default='000000000')
replenish_threshold = models.IntegerField(max_length=1000, default=10)
max_onhand = models.IntegerField(max_length=10000, default=30)
introduction = models.DateField(auto_now=True)
tags = models.ManyToManyField(Tag)
slug = models.SlugField(max_length=100, default=slugify(name))
class Meta:
verbose_name_plural = 'items'
def __str__(self):
return self.name
class OnHand(models.Model):
name = models.CharField(max_length=100)
serial = models.CharField(max_length=80, default='Consumable')
asset = models.CharField(max_length=20, null=True, blank=True)
product = models.ForeignKey(Item, blank=True, null=True, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
class Meta:
verbose_name_plural = 'items on hand'
def __str__(self):
if not self.serial:
return self.name
return self.serial
I have a ModelForm I use for adding new Items and OnHand, the form I'm working with is at /inventory/add_onhand// so /inventory/add_onhand/1/ would be the form to add a keyboard to inventory for Item with a primary key of 1.
class OnHandForm(forms.ModelForm):
class Meta:
model = OnHand
fields = {'name', 'asset', 'serial',}
def add_onhand(request, query):
if request.method == "POST":
form = OnHandForm(request.POST)
if form.is_valid():
form.save()
return redirect('view_item')
else:
print(query)
form = OnHandForm()
item = Item.objects.get(pk=query)
return render(request, 'add_onhand.html', {'form':form, 'item':item})
When saving a new OnHand via this form, how would I direct the relationship to Item?
I am still hoping for a better solution, but in the meantime what I've done was added product to the form, but using JQuery to hide the element and automatically select it based on the Item's primary key.
This is hacky, but it works. I'd hope for a more elegant solution.
My problem whith django-autocomplete-light (dal 3) is that in the admin, instead of showing the choices corresponding tom my designated field (i.e. birth_nation see forms.py section), I always get a list of the str values of my queryset objects (see #models.py section) which is actually the last_name field.
# models.py
class MyModel(models.Model):
id_name = models.CharField(primary_key=True, max_length=255)
first_name = models.CharField(max_length=255, blank=True, null=True)
middle_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255)
birth_city = models.CharField(max_length=255, blank=True, null=True)
birth_nation = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return self.last_name
class Meta:
managed = False
db_table = 'mytable'
# forms.py
class MyModelForm(forms.ModelForm):
birth_nation = forms.ModelChoiceField(
queryset=MyModel.objects.all(),
widget=autocomplete.ModelSelect2(url='country-autocomplete',
attrs={'data-minimum-input-length': 2}
)
)
class Meta:
model = MyModel
fields = ('__all__')
# views.py
class MyModelAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated():
return MyModel.objects.none()
qs = MyModel.objects.all()
if self.q:
qs = qs.filter(birth_nation__istartswith=self.q)
return qs
Obviously, I want to get my choices that correspond to the birth_nation, what is wrong in my code?
try this:
def __str__(self):
return self.birth_nation
Autocomplete return value is a query object. If you want to see specific field in the object, write that field in your model class or change your autocomplete class return value.
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.