Column 'user_id' cannot be null django - mysql

I seek to create a post with a form where a registered user creates and inserts the primary key id in the db but this does not give me the following error Column 'user_id' can not be null
This is my models.py
class posts(models.Model):
titulo = models.CharField(max_length=180, unique=True)
slug = models.SlugField(max_length=180, editable=False)
contenido = models.TextField()
categoria = models.ForeignKey(categorias)
user = models.ForeignKey(User)
tags = models.CharField(max_length=200)
creado = models.DateTimeField(auto_now_add=True)
modificado = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.titulo)
super(posts, self).save(*args, **kwargs)
def __str__(self):
return self.titulo
This is my view.py
def addPosts(request):
if request.method == "POST":
form = addPostForm(request.POST)
if form.is_valid():
add = form.save(commit=False)
#add.user = User.objects.get(id=request.user)
add.save()
form.save_m2m()
return HttpResponseRedirect('/')
else:
form = addPostForm ()
ctx = {'form': form}
return render_to_response('posts/add.html', ctx, context_instance=RequestContext(request))
This is forms.py
class addPostForm(forms.ModelForm):
class Meta:
model = posts
exclude = {'slug','user', 'creado'}
some solution to this problem?

Request.user returns the current user object. No need to do a lookup.
add.user = request.user
in your view

If tying to the Django built-in user, you're going to want to do it differently from your model:
user = models.ForeignKey(User)
Consider defining this in your settings and instead, use:
user = models.ForeignKey(settings.AUTH_USER_MODEL)
See the documentation here: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#referencing-the-user-model
This will also future-proof you if you decide to extend the Django base user model in the future.

Related

Django complete form as signed up user

After you sign up, you are prompted to a page that contains a form used for gathering additional information about the new user and after that it redirects you to the login page. The problem is that the form doesn't submit if i don't specify the {{form.user}} instance in the html file. Probably because the user_id is not recognized by default. When i specify it, the form let me chooses from already existing users, and i would like it to go with the logged in user by default.
views.py
class CreateInfoView(CreateView):
model = AdditionalInfoModel
form_class = AdditionallnfoModelForm
template_name = "user_ski_experience/additional_info.html"
def get_form_kwargs(self):
variable_to_send = super(CreateInfoView, self).get_form_kwargs()
variable_to_send.update({'pk': None})
variable_to_send.update({'pk_user': self.request.user.pk})
return variable_to_send
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
def get_success_url(self):
return reverse('login')
forms.py
class AdditionallnfoModelForm(forms.ModelForm):
class Meta:
model = AdditionalInfoModel
fields = '__all__'
def __init__(self, pk, *args, **kwargs):
pk_user = kwargs.pop('pk_user')
super(AdditionallnfoModelForm, self).__init__(*args, **kwargs)
self.pk = pk
self.fields['user'].disabled = True
self.fields['user'].initial = pk_user
for el in self.fields:
self.fields[el].label = False
def clean(self):
return self.cleaned_data
How can i solve this ?
class AdditionalInfoModel(models.Model):
objects = None
skill_choices = (('Beginner', 'BEGINNER'),
('Intermediate', 'INTERMEDIATE'),
('Expert', 'EXPERT'))
user = models.OneToOneField(User, on_delete=models.CASCADE)
country = models.CharField(max_length=30, blank=True)
city = models.CharField(max_length=30, blank=True)
assumed_technical_ski_level = models.CharField(max_length=30,
choices=skill_choices)
years_of_experience = models.PositiveIntegerField(blank=True)
money_to_spend = models.PositiveIntegerField(blank=True)
resort_choice = models.ForeignKey(Resorts, on_delete=models.CASCADE,
blank = True, null = True)
def __str__(self):
return self.user.username

`category` and `tag` shared by multiple wagtail page types

I have a Django+Wagtail website, and have category and tag created to be applied to blog posts.
from taggit.models import Tag as TaggitTag
from taggit.models import TaggedItemBase
class PostList(RoutablePageMixin, Page):
template = "Post_List.html"
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel("intro")
]
subpage_types = [
"PostDetail",
]
parent_page_type = [
"HomePage",
]
# Each 'search / category / tag / author' will generate a separate 'PostList' page with its own 'context',
# hence for 'Pagination' for all 'PostList' pages, we only need to implement in 'get_context()'
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
# For Pagination
page_id = request.GET.get("page")
paginator = Paginator(self.posts, 3) # 'posts' is defined in 'def post_list()' and 'def get_posts()' as below.
try:
paginator_page = paginator.page(page_id)
except PageNotAnInteger:
paginator_page = paginator.page(1)
page_id = 1
except EmptyPage:
paginator_page = paginator.page(1)
page_id =1
context['paginator_page'] = paginator_page
context['total_num_pages'] = paginator.num_pages
# By default, Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)
context['elided_page_range'] = paginator.get_elided_page_range(page_id, on_each_side=5, on_ends=2)
return context
def get_posts(self):
return PostDetail.objects.descendant_of(self).live()
#route(r'^tag/(?P<tag>[-\w]+)/$')
def post_by_tag(self, request, tag, *args, **kwargs):
self.search_type = 'tag'
self.search_term = tag
self.posts = self.get_posts().filter(tags__name=tag)
return Page.serve(self, request, *args, **kwargs)
#route(r'^category/(?P<category>[-\w]+)/$')
def post_by_category(self, request, category, *args, **kwargs):
self.search_type = 'category'
self.search_term = category
self.posts = self.get_posts().filter(categories__category__name=category)
return Page.serve(self, request, *args, **kwargs)
#route(r'^user/(?P<user>[-\w]+)/$')
def post_by_user(self, request, user, *args, **kwargs):
self.search_type = 'user'
self.search_term = user
self.posts = self.get_posts().filter(owner__username=user)
return Page.serve(self, request, *args, **kwargs)
#route(r'^$')
def post_list(self, request, *args, **kwargs):
self.posts = self.get_posts()
return Page.serve(self, request, *args, **kwargs)
#route(r'^search/$')
def post_search(self, request, *args, **kwargs):
search_query = request.GET.get('q', None)
self.posts = self.get_posts()
if search_query:
self.posts = self.posts.filter(body__contains=search_query)
self.search_term = search_query
self.search_type = 'search'
return Page.serve(self, request, *args, **kwargs)
class PostDetail(Page):
template = "Post_Detail.html"
body = MarkdownField()
tags = ClusterTaggableManager(through="PostDetailTag", blank=True)
#register_snippet
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=100)
panels = [
FieldPanel("name"),
FieldPanel("slug"),
]
def __str__(self):
return self.name
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ["name"]
#register_snippet
class Tag(TaggitTag):
class Meta:
proxy = True
# Intermediate Models for ManyToMany Relationship
class PostDetailCategory(models.Model):
post = ParentalKey("PostDetail", on_delete=models.CASCADE, related_name="categories")
category = models.ForeignKey("Category", on_delete=models.CASCADE, related_name="post_details")
panels = [
SnippetChooserPanel("category"),
]
class Meta:
unique_together = ("post", "category")
class PostDetailTag(TaggedItemBase):
content_object = ParentalKey("PostDetail", on_delete=models.CASCADE)
Now, I am about to creating another wagtail page type "SurveyPoll", and want to have tag and category applied as well.
What is the best practice for this deployment, same tag and category applied to different wagtail page types via ManyToMany relationship ?
Which type of ManyToMany relationship deployment is better, tag or category ? Personally, I prefer the category way as it allows me to choose from a list of existing category in wagtail admin edit page.

Data not saving in database in Django

I am trying to save data into the database from the website. My web page is taking the data (image from my system) but in the database, it's not showing up. If I add manually then it's creating a new user entry and storing it.
Here are my files:
models.py
class Details(models.Model):
name = models.CharField(max_length=122)
username = models.CharField(max_length=122)
email = models.EmailField(max_length=122)
password = models.CharField(max_length=20)
def __str__(self):
return self.name
class Image_Data(models.Model):
img_User = models.ForeignKey(
Details, blank=True, null=True, on_delete=models.CASCADE)
img_password = models.ImageField(null=True, blank=True)
def __str__(self):
return str(self.img_password)
forms.py
class ImageForm(ModelForm):
class Meta:
model = Image_Data
fields = ('img_password',)
labels = {
'img_password': 'Add your image ',
}
widgets = {
'img_password': forms.FileInput(attrs={'class': 'form-control', 'placeholder': 'Upload from device'})
}
views.py
def register_new_b(request):
saved = False
if request.method == "POST":
# take whatever is posted to the Details Form
form = ImageForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your message has been sent!')
return HttpResponseRedirect('/register_new_b?saved=True')
else:
form = ImageForm()
if 'saved' in request.GET: # sends saved var in GET request
saved = True
return render(request, 'register2.html', {'form': form, 'saved': saved})
Here is what I get in database upon saving the image
In the line:
form = ImageForm(request.POST)
you need to add request.FILES:
form = ImageForm(request.POST, request.FILES)
*Edit
An working example inside my own code:
in views.py
def change_profile_pic(request):
context = dict()
if request.method == 'POST':
form = ProfilePictureForm(request.POST, request.FILES)
if form.is_valid():
form.store(request.user.id)
form = ProfilePictureForm()
context['success_message'] = 'Picture changed'
request.user.employee.refresh_from_db()
else:
context['error_message'] = 'Unable to change picture'
else:
form = ProfilePictureForm()
context['form'] = form
return render(request, 'template.html', context)
in forms.py
class ProfilePictureForm(forms.Form):
image = forms.ImageField(required=True)
def store(self, user_id):
user = User.objects.get(id=user_id)
user.employee.profile_picture = self.cleaned_data['image']
user.employee.save()
in models.py
class Employee(models.Model):
user = models.OneToOneField(User, blank=False, on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='profile_pictures', max_length=200, null=True, blank=True)
But I have also experimented with ModelForm, and this also saves the file correcly

__init__() got an unexpected keyword argument 'use_required_attribute'

I don't know why in some pages give me this error, and in others dosen't show me the error
I try to add a requiered attrbute but dosen't work, I don't how to add it
Model
class Vehicle(models.Model):
registration = models.CharField(max_length=200, default='')
vehicle_type = models.ForeignKey(VehicleType, on_delete=models.CASCADE)
def __str__(self):
return self.registration
class Meta:
verbose_name_plural = "Vehicles"
Form
class VehicleForm(ModelForm):
class Meta:
model = Vehicle
fields = ['registration', 'vehicle_type']
View
def vehicles(request):
vehicles = Vehicle.objects.all()
context = {
'title' : 'Vehicles',
'generic_objects' : vehicles
}
return render(request, 'vehicle/index.html',context)
def vehicle(request, id):
VehicleFormSet = modelformset_factory(Vehicle, exclude=(), extra=0)
#Add a vehicle
if request.method == 'POST':
formset = VehicleFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return HttpResponseRedirect('/favorita/vehicles')
#Edit the vehicle
else:
vehicles_search = Vehicle.objects.filter(id = id)
if vehicles_search:
formset = VehicleFormSet(queryset=vehicles_search)
else:
formset = formset_factory(VehicleForm)
return render(request, 'vehicle/details.html', {'formset': formset, 'id':id, 'title':"Vehicle"})
def delete_vehicle(request, id):
Vehicle.objects.filter(id=id).delete()
return HttpResponseRedirect('/favorita/vehicles')
The error image

Django IntegrityError: (1048, "Column 'user_id' cannot be null")

This is my models.py
class Cfituser(models.Model):
user = models.OneToOneField(User)
socialid = models.IntegerField(null=True)
accesstoken = models.CharField(max_length=255L, null = True)
class Meta:
db_table = 'CfitUser'
def __str__(self):
return "%s's profile" % self.user
#receiver(post_save, sender=User)
def create_cfituser(sender, instance, created, **kwargs):
if created:
Cfituser.objects.get_or_create(user=instance)
This is my views.py
#api_view(['GET', 'POST'])
def users_create(request, format = None):
"""
List all users, or create a new user.
"""
if request.method == 'GET':
cfituser = Cfituser.objects.all()
serializer = CfituserSerializer(cfituser, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = CfituserSerializer(data=request.DATA)
if serializer.is_valid():
print serializer.data
user = User.objects.create_user(username = serializer.data['socialid'])
cfituser = Cfituser.objects.get(user = user)
cfituser.accesstoken = serializer.data['accesstoken']
cfituser.socialid = serializer.data['socialid']
cfituser.save()
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Whenever there is a HTTP Post request, my database tables are filled in as expected but this error keeps popping up. I've tried almost every solution available on SO but I'm stuck with this.
I have tried user = models.OneToOneField(User, null = True) but this leads to two entries in my database table, one with user_id = NULL and one with user_id = actualvalue.
Any suggestions on how to fix this?
Saving by default commits the entry to the database, to prevent that, pass commit=False to save(), and then do your customizations.
serializer = serializer.save(commit=False)
user, created = User.objects.get_or_create(username = serializer.socialid)
cfituser, created = Cfituser.objects.get_or_create(user = user)
# cfituser.user = user This line is unnecessary
cfituser.accesstoken = serializer.accesstoken
cfituser.socialid = serializer.socialid
cfituser.save()
serializer.save()
You are also duplicating your efforts because your signal will also attempt to create a user. If you are on django 1.5, use customized user model; and for social registration/oauth, use django-social-auth.
OneToOneField means, in Cfituser.user the reverse side of the relation will directly return a single object(user.cfituser gives Cfituser). SO Cfituser.user must be unique through out the table(one and only one).
class Cfituser(models.Model):
user = models.OneToOneField(User)
socialid = models.IntegerField(null=True)
accesstoken = models.CharField(max_length=255L, null = True)
def __unicode__(self):
return "%s's profile" % self.user.username
def users_create(request, format = None):
"""
List all users, or create a new user.
"""
if request.method == 'GET':
cfituser = Cfituser.objects.all()
serializer = CfituserSerializer(cfituser, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = CfituserSerializer(data=request.DATA)
if serializer.is_valid():
print serializer.data
user = User.objects.create_user(username = serializer.data['socialid'])
Cfituser(user = user,accesstoken = serializer.data['accesstoken'],socialid = serializer.data['socialid']).save()
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)