How to solve user updating problem in Django - python

I created a system with Django. I need user update section for this project. At the beginning of the project the user change form was working but now it doesnt work. I have a hiden field in my form and I think that's the problem but I'm not sure. Can you help me?
view.py
def update_user(request, id):
user = get_object_or_404(UserProfile, id=id)
form = SignUpForm(request.POST or None, request.FILES or None, instance=user)
if form.is_valid():
form.save()
return redirect('/')
context = {
'form': form,
}
return render(request, "update_user.html", context)
models.py
class UserProfile(AbstractUser):
ranks = (
('Analyst', 'Analyst'),
...
('Chief Financial Officer', 'Chief Financial Officer'),
)
comp_name = models.CharField(max_length=200, default='', blank=True, null=True)
user_id = models.UUIDField(default=uuid.uuid4(), editable=False, unique=True)
....
rank = models.CharField(max_length=200, choices=ranks)
image = models.ImageField(upload_to='profile_image', blank=True, null= True, default='profile.png')
def __str__(self):
return self.username
def get_unique_slug(self):
slug = slugify(self.slug.replace('ı', 'i'))
unique_slug = slug
counter = 1
while UserProfile.objects.filter(slug=unique_slug).exists():
unique_slug = '{}-{}'.format(slug, counter)
counter += 1
return unique_slug
forms.py
class SignUpChangeForm(UserChangeForm):
class Meta:
model = UserProfile
fields = (
'username', 'first_name', 'last_name', 'email', 'rank', 'comp_name', 'image'
)
def clean_password(self):
return self.clean_password
update_user.html
<form method="post">
{{ form|crispy }}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
{% csrf_token %}
<button type="submit" class="btn btn-success">Update</button>
</form>
Error in the form

Related

Django create parent model and child model in one form

I am learning Python and Django, and I am trying to create a recipe with a form. The problem is I have two models, Recipe and RecipeIngredient and I don't know how to add recipe ingredients to the form since it requires the primary key of the recipe and from what I understand, the key is not created until after the form is saved? So how can I create a recipe with both the Recipe and RecipeIngredient when Recipe is not yet initialized?
Models.py:
class Recipe(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image = models.ImageField(upload_to='image/', blank=True, null=True)
name = models.CharField(max_length=220) # Lasanga
description = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)
cookTime = models.CharField(max_length=50, blank=True, null=True)
timeStamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
#property
def title(self):
return self.name
def get_absolute_url(self):
return reverse("recipes:detail", kwargs={"id": self.id}) # recipes is from url.py app_name
def get_hx_url(self):
return reverse("recipes:hx-detail", kwargs={"id": self.id}) # recipes is from url.py app_name
def get_edit_url(self):
return reverse("recipes:update", kwargs={"id": self.id})
def get_image_upload_url(self):
return reverse("recipes:recipe-ingredient-image-upload", kwargs={"parent_id": self.id})
def get_delete_url(self):
return reverse("recipes:delete", kwargs={"id": self.id})
def get_ingredients_children(self):
return self.recipeingredient_set.all()
def get_instruction_children(self):
return self.recipeinstruction_set.all()
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
name = models.CharField(max_length=220) # grilled chicken pasta
description = models.TextField(blank=True, null=True)
quantity = models.CharField(max_length=50, blank=True, null=True)
unit = models.CharField(max_length=50, validators=[validate_unit_of_measure], blank=True, null=True)
instructions = models.TextField(blank=True, null=True)
timeStamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
def get_absolute_url(self):
return self.recipe.get_absolute_url() # recipe cannot be none
def get_hx_edit_url(self):
kwargs = {
"parent_id": self.recipe.id,
"id": self.id
}
return reverse("recipes:hx-ingredient-detail", kwargs=kwargs)
def get_delete_url(self):
kwargs = {
"parent_id": self.recipe.id,
"id": self.id
}
return reverse("recipes:ingredient-delete", kwargs=kwargs)
Views.py
#login_required
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
context = {
"form": form,
}
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
if request.htmx: # necessary to pass headers from htmx response if we want the django to recognise the htmx change
headers = {
"HX-Redirect": obj.get_absolute_url()
}
return HttpResponse("Created", headers=headers)
# if request.htmx: # could use this but the url doesn't update, stays as create, would need to use HX-Push header & HttpResponse + context somehow
# context = {
# "object": obj
# }
# return render(request, "recipes/partials/detail.html", context)
return redirect(obj.get_absolute_url())
return render(request, "recipes/create.html", context)
#login_required
def recipe_ingredient_update_hx_view(request, parent_id=None, id=None): # this is both create & edit, can create
if not request.htmx:
raise Http404
try:
parent_obj = Recipe.objects.get(id=parent_id, user=request.user)
except:
parent_obj = None
if parent_obj is None:
return HttpResponse("Not Found.")
instance = None
if id is not None:
try:
instance = RecipeIngredient.objects.get(recipe=parent_obj, id=id) # think of this as an object if that helps
except:
instance = None
form = RecipeIngredientForm(request.POST or None, instance=instance)
url = reverse("recipes:hx-ingredient-create", kwargs={"parent_id": parent_obj.id})
if instance:
url = instance.get_hx_edit_url()
context = {
"url": url,
"form": form,
"object": instance
}
if form.is_valid():
new_obj = form.save(commit=False)
if instance is None:
new_obj.recipe = parent_obj
new_obj.save()
context['object'] = new_obj # because it's possible the object/instance in None
return render(request, "recipes/partials/ingredient-inline.html", context)
return render(request, "recipes/partials/ingredient-form.html", context)
forms.py
from django import forms
from .models import Recipe, RecipeIngredient
class RecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'image', 'description', 'notes', 'cookTime']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
new_data = {
"placeholder": f"Recipe {str(field)}",
"class": "form-control",
}
self.fields[str(field)].widget.attrs.update(new_data)
class RecipeIngredientForm(forms.ModelForm):
class Meta:
model = RecipeIngredient
fields = ['name', 'quantity', 'unit']
urls.py
from django.urls import path
from .views import (
recipe_list_view,
recipe_delete_view,
recipe_create_view,
recipe_update_view,
recipe_detail_hx_view,
recipe_ingredient_update_hx_view,
recipe_ingredient_delete_view,
recipe_ingredient_image_upload_view,
recipe_ingredient_url_scrape_view
)
app_name='recipes' # allows use of recipes:list as a reverse url call
urlpatterns = [
path('', recipe_list_view, name='list'), # index / home / root
path('create/>', recipe_create_view, name='create'),
path('hx/<int:parent_id>/ingredient/<int:id>', recipe_ingredient_update_hx_view, name='hx-ingredient-detail'), #or detail
path('hx/<int:parent_id>/ingredient/', recipe_ingredient_update_hx_view, name='hx-ingredient-create'),
]
create.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
<div class="container-fluid px-5">
<h1 class="pb-5">Create Recipe</h1>
<div id="recipe-container">
<form action='.' method="POST" hx-post='.'>
{% csrf_token %}
<div class='row'>
<div class="row d-flex pb-5">
<div class="col-12 col-lg-6 justify-content-center d-flex order-first order-lg-last pictureBox"
style="height: 400px; width:450; border: solid tomato 1px;">
<div class="align-self-center">
{{ form.image|as_crispy_field }}
</div>
</div>
<div class="col-12 col-lg-6 order-lg-first">
<div class="pb-3">{{ form.name|as_crispy_field }}</div>
<div class="pb-3">{{ form.description|as_crispy_field }}</div>
</div>
</div>
<div class="col-12 col-md-6">
{{ form.notes|as_crispy_field }}
</div>
<div class="col-12 col-md-6">
{{ form.cookTime |as_crispy_field }}
</div>
</div>
</div>
<div class='col-12 col-md-4'>
<!-- ADD INGREDIENTS ? -->
</div>
<div class="htmx-indicator">Loading...</div>
<div class="d-flex">
<button class="btn btn-success htmx-inverted-indicator" style='margin-top:10px;' type='submit'>Save</button>
<a class="btn btn-danger" href='{% url "recipes:list" %}'>Delete</a>
</div>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</form>
</div>
</div>
{% endblock content %}
ingredient-form.html
<form action='.' method="POST" hx-post='{% if url %} {{ url }} {% else %} . {{% endif %}' hx-swap='outerHTML'>
{% csrf_token %}
{{ form.as_p}}
<div class="htmx-indicator">Loading...</div>
<button class="htmx-inverted-indicator" style='margin-top:10px;' type='submit' >Save</button>
</form>
ingredient-inline.html
<div class="py-1" id="ingredient-{{object.id}}">
<p>{% if not edit %} <b>{{ object.quantity }} {% if object.unit %} {{ object.unit }} {% endif %}</b> {% else %} {{ object.quantity }} {{ object.unit }} {% endif %} - {{ object.name }}</p>
{% if edit %}
<button class="btn btn-primary" hx-trigger='click' hx-get='{{ object.get_hx_edit_url }}' hx-target="#ingredient-{{object.id}}">Edit</button> <!-- target will replace whole div-->
<button class="btn btn-danger" href='{{ object.get_delete_url }}' hx-post='{{ object.get_delete_url }}' hx-confirm="Are you sure you want to delete {{ object.name }}?" hx-trigger='click' hx-target="#ingredient-{{object.id}}" hx-swap="outerHTML">Delete</button>
{% endif %}
</div>
The key to this problem is using a formset, as you will likely want to save multiple ingredients to the recipe. Django documentation outlines how to use them. Your view would end up looking something like below, allowing you to save the parent model, which will give you the parent instance/primary key to then save the ingredients.
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
RecipeIngredientFormset = formset_factory(RecipeIngredientForm)
formset = RecipeIngredientFormset(request.POST or None)
context = {
"form": form,
"formset": formset,
}
if request.method == "POST":
if form.is_valid() and formset.is_valid():
parent = form.save(commit=False)
parent.user = request.user
parent.save()
#recipe ingredients
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()

Django Tags save related objects

Good day all!
I'm trying to make a save form with some kind of fields, where each field has its own tag and only one.
But when I save the form, I have one field that saves not one tag but two at once. Although this should not be. Help me solve the issue please.
/models.py
class Post(models.Model): # Books
user = models.ForeignKey(User, on_delete=models.CASCADE)
image = VersatileImageField(
'Image',
upload_to='media_my/',null=True,
blank=True
)
title = models.CharField(max_length=150, db_index=True)
slug = models.SlugField(max_length=150, unique=True, blank=True)
tags = models.ManyToManyField('Tag', blank=True, related_name='posts')
b1 = models.ManyToManyField('B1', blank=False, related_name='bo1')
b2 = models.ManyToManyField('B2', blank=False, related_name='bo2')
b3 = models.ManyToManyField('B3', blank=False, related_name='bo3')
b4 = models.ManyToManyField('B4', blank=False, related_name='bo4')
date_pub= models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse('post_detail_url', kwargs={'slug':self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug= gen_slug(self.title)
super().save(*args, **kwargs)
def __str__(self):
return self.title
class Meta:
ordering = ['-date_pub']
class Tag(models.Model): # Tags of books
title=models.CharField(max_length=50)
slug=models.SlugField(max_length=50, unique=True)
def get_absolute_url(self):
return reverse('tag_detail_url', kwargs={'slug': self.slug})
def __str__(self):
return self.title
class B1(models.Model):
b1 = models.CharField(max_length=286)
tags = models.ManyToManyField('Tag', blank=True, related_name='t1')
date_save= models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.b1
class B2(models.Model):
b2 = models.CharField(max_length=286)
tags = models.ManyToManyField('Tag', blank=True, related_name='t2')
date_save= models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.b2
class B3(models.Model):
b3 = models.CharField(max_length=286)
tags = models.ManyToManyField('Tag', blank=True, related_name='t3')
date_save= models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.b3
class B4(models.Model):
b4 = models.CharField(max_length=286)
tags = models.ManyToManyField('Tag', blank=True, related_name='t4')
date_save= models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.b4
/forms.py
class TagForm(forms.ModelForm):
class Meta:
model = Tag
fields = ['title','slug']
widgets= {
'title':forms.TextInput(attrs={'class':'form-control'}),
'slug':forms.TextInput(attrs={'class':'form-control'}),
}
def clean_slug(self):
new_slug=self.cleaned_data['slug'].lower()
if new_slug== 'create':
raise ValidationError('Slug may not be "Create"')
if Tag.objects.filter(slug__iexact=new_slug).count():
raise ValidationError('Slug must be unique. We have "{}" slug already'.format(new_slug))
return new_slug
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [ 'image','title','tags']
widgets = {
'image':forms. ClearableFileInput(attrs={'class':'form-control'}),
'title': forms.TextInput(attrs={'class':'form-control'}),
'tags': forms.SelectMultiple(attrs={'class':'form-control'}),
}
def clean_slug(self):
new_slug = self.cleaned_data['slug'].lower()
if new_slug =='create':
raise ValidationError('Slug may not be "Create"')
return new_slug
class B1Form(forms.ModelForm):
class Meta:
model = B1
fields = ['b1','tags']
widgets = {
'b1': forms.TextInput(attrs={'class':'form-control'}),
'tags': forms.SelectMultiple(attrs={'class':'form-control'}),
}
class B2Form(forms.ModelForm):
class Meta:
model = B2
fields = [ 'b2','tags']
widgets= {
'b2': forms.TextInput(attrs={'class':'form-control'}),
'tags': forms.SelectMultiple(attrs={'class':'form-control'}),
}
class B3Form(forms.ModelForm):
class Meta:
model = B3
fields = [ 'b3','tags']
widgets= {
'b3': forms.TextInput(attrs={'class':'form-control'}),
'tags': forms.SelectMultiple(attrs={'class':'form-control'}),
}
class B4Form(forms.ModelForm):
class Meta:
model = B4
fields = [ 'b4']
widgets= {
'b4': forms.TextInput(attrs={'class':'form-control'}),
}
/ HTML
{% extends 'face/base_face.html'%}
{% block title %}
Create Post - {{ block.super}}
{% endblock %}
{% block content %}
<form class="" action="{% url 'post_create_url' %}" method="post" enctype="multipart/form-data">
{% csrf_token%}
<!-- forma of Post -->
{% for field in form %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{ field.errors }}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<!-- forma of B1 -->
{% for field in forma %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{field.errors}}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<!-- forma of B2 -->
{% for field in formb %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{field.errors}}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<!-- forma of B3 -->
{% for field in formc %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{field.errors}}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<!-- forma of B4 -->
{% for field in formd %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{field.errors}}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
/utils.py
def get(self, request):
form= self.model_form()
forma= self.modb1()
formb= self.modb2()
formc= self.modb3()
formd= self.modb4()
context = {
'form':form,
'forma':forma,
'formb':formb,
'formc':formc,
'formd':formd,
}
return render (request, self.template, context)
def post(self, request):
bound_form = self.model_form(request.POST or None, request.FILES or None)
bp1=self.modb1(request.POST or None)
bp2=self.modb2(request.POST or None)
bp3=self.modb3(request.POST or None)
bp4=self.modb4(request.POST or None)
context = {'form':bound_form,'forma':bp1,
'formb':bp2,'formc':bp3,
'formd':bp4,}
if bound_form.is_valid() and bp1.is_valid() and bp2.is_valid() and bp3.is_valid() and bp4.is_valid():
new_obj=bound_form.save(commit=False)
new_obj.user = request.user
new_obj.b1.add(a)
new_obj.b2.add(b)
new_obj.b3.add(c)
new_obj.b4.add(d)
a=bp1.save()
b=bp2.save()
c=bp3.save()
d=bp4.save()
new_obj.save()
return redirect(new_obj)
Please look carefully at my code in the forms.py
Maybe the tags are incorrect in the fields B1, B2, B3, B4 ?

The view students.views.addgrregister didn't return an HttpResponse object. It returned None instead

ValueError at /students/addgrregister/
i am trying to add students in gr_register but its giving an error due to this error the code is not working i also upload the template (addgrregister.html) kndly tell me where is the issue in these pages
models.py
class gr_register(models.Model):
Gender_Choices = (
('M', 'Male'),
('FM', 'Female'),
)
Status_Choices = (
('P', 'Present'),
('FM', 'Left'),
)
gr_no = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_birth = models.DateField(null=True)
classes_A = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_A", default=1, verbose_name="Class of Admission")
sections_A = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_A", default=1, verbose_name="Section of Admission")
gender = models.CharField(max_length=10, choices=Gender_Choices)
classes_C = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_C", verbose_name="Current Class")
sections_C = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_C", verbose_name="Current Section")
address = models.CharField(max_length=100, null=True, verbose_name="Home Address")
area_code = models.ForeignKey(Area, on_delete=models.CASCADE, verbose_name="Area")
status = models.CharField(max_length=10, choices=Status_Choices, default='P')
class Meta:
ordering = ('gr_no',)
def __str__(self):
return self.first_name
views.py
from django.shortcuts import get_object_or_404, render, redirect
def addgrregister(request):
if request.method == 'POST':
form = gr_registerForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = gr_registerForm()
return render(request, 'students/addgrregister.html', {'form': form})
forms.py
from django import forms
from django.forms import ModelChoiceField, ModelForm
from .models import *
class gr_registerForm(ModelForm):
classes_A = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_A = forms.ModelChoiceField(queryset=Sections.objects.all())
classes_C = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_C = forms.ModelChoiceField(queryset=Sections.objects.all())
area_code = forms.ModelChoiceField(queryset=Area.objects.all())
class Meta:
model = gr_register
fields = '__all__'
def init(self, *args, **kwargs):
forms.ModelForm.init(self, *args, **kwargs)
addgrregister.html
{% extends 'authenticate/base.html' %}
{% block content %}
<div class="container">
<h4 class="text-center">ADD GR_REGISTER</h4>
<hr/>
<form method="POST" action="{% url 'addgrregister' %}" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="button">Add GR_REGISTER</button>
</form>
<br/><br/>
</div>
{% endblock %}
There is nothing returned when form is not valid. I think you try like this:
def addgrregister(request):
form = gr_registerForm(request.POST or None) # it initates a form. If the request type is POST, then there will be a dict available with posted data in request.POST. If request is not POST, then the form will initiate with empty data.
if request.method == 'POST':
if form.is_valid(): # Form valid checks if the submitted form is valid or not. If not, it will store errors in the form. When that form is passed to template, it will show errors in html
form.save() # It will store data in DB
return redirect('home')
# when for is invalid, it will show the error in the form
return render(request, 'students/addgrregister.html', {'form': form})
Update
Show form errors in template:
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
{{ field.errors }} // <-- Updated here
</div>
</div>
{% endfor %}

Django create user profile at the time of registration from submission

I am working on a Role Based Access Control system on django.where at the signup/register people will be designated to a 'department' and will be assigned a 'role' Hence I created a custom user model
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
DEPARTMENT_CHOICES = (
('Production', 'Production'),
('Marketing', 'Marketing'),
('IT', 'IT'),
('HR', 'HR'),
('Accounts', 'Accounts'),
)
ROLE_CHOICES = (
('Manager', 'Manager'),
('Team Lead', 'Team Lead'),
('Member', 'Member'),
)
user = models.OneToOneField(
User,)
department = models.CharField(
max_length=50, choices=DEPARTMENT_CHOICES, null=True)
role = models.CharField(max_length=50, choices=ROLE_CHOICES, null=True)
def __unicode__(self):
return unicode(self.user.first_name + ' ' + self.user.last_name)
def __str__(self):
return self.user.first_name + ' ' + self.user.last_name
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = Profile.objects.create(user=kwargs['instance'])
pass
post_save.connect(create_profile, sender=User)
Then i created a form like
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Profile
class SignUpForm(UserCreationForm):
DEPARTMENT_CHOICES = (
('Production', 'Production'),
('Marketing', 'Marketing'),
('IT', 'IT'),
('HR', 'HR'),
('Accounts', 'Accounts'),
)
ROLE_CHOICES = (
('Manager', 'Manager'),
('Team Lead', 'Team Lead'),
('Member', 'Member'),
)
first_name = forms.CharField(
max_length=30, required=True, help_text='Optional.')
last_name = forms.CharField(
max_length=30, required=True, help_text='Optional.')
email = forms.EmailField(
max_length=254, required=False)
department = forms.ChoiceField(choices=DEPARTMENT_CHOICES, )
role = forms.ChoiceField(choices=ROLE_CHOICES, )
class Meta:
model = User
fields = ('first_name', 'last_name', 'username',
'email', 'password1', 'password2', 'department', 'role')
The my views
from django.shortcuts import render, redirect, render_to_response
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from .forms import SignUpForm
from .models import Profile
from django.shortcuts import get_object_or_404
from django.http import Http404
from django.contrib.auth.models import User
from django.template import RequestContext
def register(request):
if request.user.is_authenticated:
if request.user.is_superuser or request.user.role == 'Manager':
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
userprofile = Profile.objects.update(
user=user, department=form.cleaned_data['department'])
userprofile = Profile.objects.update(
user=user, role=form.cleaned_data['role'])
else:
form = SignUpForm()
c = {
'form': form,
}
return render(request, 'registration/register.html', c)
else:
raise Http404
else:
raise Http404
my register.html
{% extends 'layouts/base.html' %} {% load widget_tweaks %}{% block additionalbottom %}
<script>
var allParas = document.getElementsByTagName('div');
//filter by class name if desired...
for (var i = 0; i < allParas.length; i++) {
if (allParas[i].getElementsByTagName('*').length == 0) {
allParas[i].style.display = 'none';
}
}
</script>
{% endblock %} {% block content %}
<div class="login-page">
<div class="form">
<h2>User Registration</h2>
<form class="login-form" method="post">
{% csrf_token %}
<div class="row">
{% endblock %} {% for field in form %}
<div class="col-md-6">
{% if field.name == "first_name" or field.name == "last_name" %} {% render_field field class="form-control" placeholder=field.label.capitalize %} {% endif %}
</div>
<div class="col-md-6">
{% if field.name == "username" or field.name == "email" %} {% render_field field class="form-control" placeholder=field.label.capitalize %} {% endif %}
</div>
<div class="col-md-6 form-group">
{% if field.name == "department" or field.name == "role" %} {% render_field field class="form-control" placeholder=field.label.capitalize %} {% endif %}
</div>
<div class="col-md-12">
{% if field.name == "password1" %} {% render_field field class="form-control" placeholder=field.label.capitalize %} {% endif %}
</div>
<div class="col-md-12">
{% if field.name == "password2" %} {% render_field field class="form-control" placeholder=field.label.capitalize %} {% endif %}
</div>
{% endfor %}
</div>
<div class="form-group">
<button type="submit">Register</button>
</div>
</form>
{% if form.errors %} {% for field in form %} {% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %} {% endfor %} {% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %} {% endif %}
</div>
now when ever i try to submit my form it says
IntegrityError at /register/
column user_id is not unique
i tried so many solutions from google and SO nothing seems to solve the problem can anyone tell me how to fix it or why it cannot be done if it cannot be done what is the work around
This is your problem.
Profile.objects.update(user=user, department=form.cleaned_data['department'])
This will attempt to update all profiles with the same data. If you have more than one Profile, that's not allowed, since user is a one-to-one relation.
I guess what you want to do is to create a new profile object instead. Try something like this:
Profile.objects.create(
user=user,
department=form.cleaned_data['department'],
role=form.cleaned_data['role'],
)
If you use a signal to create the Profile when you save a new User, you can use update_or_create instead.
Profile.objects.update_or_create(
user=user,
defaults={
"department": form.cleaned_data['department'],
"role": form.cleaned_data['role'],
}
)
This post helped me so much. For me, my issue was I used:
current_user = request.user
when it should have been:
current_user = form.save()

Python - Update (edit) form not showing

I have been reading the django documentation, googling for days where none have the same problem as me. It seems that method "member_edit" in "Views.py" does not return any data and therefor can not show me the form.
Hopefully, some of you can spot where I went wrong. Appreciate all the help I can get!
Models.py
class Member(models.Model):
member_no = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
email = models.CharField(max_length=50, null=True, blank=True)
reg_date = models.DateTimeField(null=True, blank=True)
class Meta:
db_table = 'Member'
Forms.py
class RegForm(forms.ModelForm):
first_name = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}),
max_length=30,
required=True)
last_name = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}),
max_length=30,
required=True)
email = forms.CharField(
widget=forms.EmailInput(attrs={'class': 'form-control'}),
required=True,
max_length=75)
reg_date = forms.DateField(widget=DateWidget(usel10n=True,bootstrap_version=3))
class Meta:
model = Member
exclude = ['last_login', 'date_joined']
fields = ['first_name', 'last_name', 'email', 'reg_date', ]
Views.py
def member_edit(request, member_no):
member = Member.objects.get(member_no=member_no)
if request.method == 'POST':
form = RegForm(request.POST or None, instance=member)
if form.is_valid():
member.first_name = form.request.POST['first_name']
member.last_name = form.request.POST['last_name']
member.email = form.request.POST['email']
member.reg_date = form.request.POST['reg_date']
member.save()
return redirect('member_overview')
return render(request, 'member/member_signup.html')
urls.py
urlpatterns = [
url(r'^member_edit/(?P<member_no>\d+)$', views.member_edit, name='member_edit')
]
member_edit.html
{% block body %}
<h1 class="logo">Members</h1>
<div class="signup">
<h2>{% trans 'Update member' %}</h2>
<form action="{% url 'member_edit' member.member_no %}" method="post" role="form">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
<label for="{{ field.label }}">{{ field.label }}</label>
<div class="col-sm-10">
{{ field }}
{% if field.help_text %}
<span class="help-block">{{ field.help_text }}</span>
{% endif %}
{% for error in field.errors %}
<label class="control-label">{{ error }}</label>
{% endfor %}
</div>
</div>
{% endfor %}
<center>
<button type="submit" class="btn btn-primary">{% trans 'Update member' %}</button>
</center>
</form>
</div>
{% endblock body %}
You're not passing the form in the context (and the template name appears to be incorrect?):
def member_edit(request, member_no):
member = Member.objects.get(member_no=member_no)
if request.method == 'POST':
form = RegForm(request.POST or None, instance=member)
if form.is_valid():
# This isn't necessary - just save the form
#member.first_name = form.request.POST['first_name']
#member.last_name = form.request.POST['last_name']
#member.email = form.request.POST['email']
#member.reg_date = form.request.POST['reg_date']
#member.save()
form.save()
return redirect('member_overview')
# Instantiate the form
form = RegForm(instance=member)
# Add a dictionary for the context
return render(request, 'member/member_edit.html', {'form': form, 'member': member)
You could make this cleaner (and easier) though with a generic class based view:
from django.views import generic
from django.urls import reverse_lazy
class UpdateMember(generic.UpdateView):
model = Member
form_class = RegForm
pk_url_kwarg = 'member_no'
template_name = 'member/member_edit.html'
success_url = reverse_lazy('member_overview')
Think I got all the attributes you need there - you can check out CCBV it's a great resource for the class based views.
Take a look at the documentation on views and templates

Categories

Resources