python - django.db.utils.IntegrityError:唯一约束失败:beachprofile_beach.beach_id
问题描述
我正在为海滩配置文件设置评论功能,并希望在 beach.html 中提交评论表单并重定向回原始海滩配置文件。
我在海滩配置文件中涉及添加评论按钮和评论列表,但问题是当我打开海滩配置文件时,我选择它告诉我 beachprofile_beach.beach_id 的唯一约束失败。所以我认为这是因为在用户查看后再次返回 beachProfile 视图并将相同的海滩信息再次存储到表中。但我真的不知道如何解决它。
这是 beachProfile 视图中的一部分,当我打开新的海滩配置文件页面时,我可以将海滩信息存储到我的表 Beach 中。
def beachProfile(request):
thisname = request.build_absolute_uri()
name = thisname.split('=')[-1].replace("%20"," ")
name2 = thisname.split('=')[-1].replace("%20","+")
oldname = name
#print(name + 'hi testing')
if oldname == '1' or oldname == '2':
name = thisname.split('=')[2].replace("%20"," ")
name = name.split('?')[0]
print(name)
name2 = thisname.split('=')[2].replace("%20","+")
name2 = name2.split('?')[0]
testsafe = thisname.split('=')[1]
testsafe = int(testsafe[0])
if testsafe == 0:
safe=True
halfsafe=False
elif testsafe == 2:
safe=False
halfsafe=False
else:
safe=False
halfsafe=True
thisBeach = requests.get("https://maps.googleapis.com/maps/api/geocode/json?address="+name2+"&key=AIzaSyAH43dAThEg8WJge9cuFa3vbnBhLRSlJDQ")
beachjson = thisBeach.json()
latitude = beachjson["results"][0]["geometry"]["location"]["lat"]
longitude = beachjson["results"][0]["geometry"]["location"]["lng"]
response = requests.get("https://api.darksky.net/forecast/fef06c56fa2906ef3255d9b99bfb02de/"+str(latitude)+","+str(longitude))
forecast = response.json()
windspeedcurr = forecast["currently"]["windSpeed"]
tempcurr = forecast["currently"]["temperature"]
uvcurr = forecast["currently"]["uvIndex"]
summary = []
for i in range(len(forecast["daily"]["data"])):
summary.append("/DarkSky-icons/PNG/"+forecast["daily"]["data"][i]["icon"]+".png")
thumbnail = "https://maps.googleapis.com/maps/api/staticmap?center="+str(latitude)+","+str(longitude)+"&zoom=14&size=400x400&key=AIzaSyAH43dAThEg8WJge9cuFa3vbnBhLRSlJDQ"
beach = Beach.objects.filter(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
).first()
if beach is None:
beach = Beach.objects.create(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
)
is_favourite=False
if oldname =='1':
"""
if beach.fav.filter(id=request.user.id).exists():
pass
else:
"""
print('adding user')
beach.fav.add(request.user)
is_favourite=True
if oldname =='2':
if beach.fav.filter(id=request.user.id).exists():
beach.fav.remove(request.user)
else:
pass
return render(request, 'users/beach.html', {'latitude': latitude, 'longitude': longitude, 'summary': summary, 'thumbnail': thumbnail, 'wind': windspeedcurr, 'temp': tempcurr, 'uvindex': uvcurr, 'name': name, 'rating': 5, 'safe': safe, 'halfsafe': halfsafe, 'is_fav':is_favourite, 'safety':testsafe})
对于我的审查模型和审查模型(部分):
class Beach(models.Model):
beach_id = models.AutoField(primary_key = True)
beachname = models.CharField(max_length=50, unique = True)
safety = models.IntegerField(default=0) #default is safe?
lat = models.IntegerField()
lng = models.IntegerField()
fav = models.ManyToManyField(User, related_name="fav",blank=True)
class Meta:
unique_together = ["beachname", "safety", "lat", "lng"]
def __str__(self):
return self.beachname
def average_rating(self):
all_ratings = map(lambda x: x.rating, self.review_set.all())
return np.mean(all_ratings)
class Review(models.Model):
review_id = models.AutoField(primary_key = True)
beach = models.ForeignKey(Beach, on_delete = models.CASCADE)
pub_date = models.DateTimeField('date published')
user_reviewed = models.ManyToManyField(User, related_name="reviewer",blank=True)
......
与海滩相关的 urls.py 主要是这样的:
url(r'^beachProfile/', beach_views.beachProfile, name='beachProfile'),
url(r'(?P<beach_id>\d+)/fav/$', beach_views.fav, name="fav"),
url(r'^$', beach_views.review_list, name='review_list'),
url(r'(?P<beach_id>\d+)/(?P<review_id>[0-9]+)/$', beach_views.review_detail, name='review_detail'),
url(r'(?P<beach_id>\d+)/add_review/$', beach_views.add_review, name='add_review'),#add review to the user with same id
url(r'^user/(?P<username>\w+)/$', beach_views.user_review_list, name='user_review_list'),
下面的代码是我添加评论的代码。我真的不知道如何在审核之前直接返回我的个人资料页面,所以我只是直接放置个人资料页面链接,但不包括最喜欢的号码(fav = 1 或 2),因为我不知道如何从海滩简介。我真的很想知道如何返回原始个人资料页面。危险是海滩模型中称为安全的计算数字,海滩名称是海滩的名称。
@login_required
def add_review(request, beach_id):
beach = get_object_or_404(Beach, beach_id=beach_id)
form = ReviewForm(request.POST)
if form.is_valid():
rating = form.cleaned_data['rating']
comment = form.cleaned_data['comment']
user_name = request.user.username
review = Review()
review.beach = beach
review.user_name = user_name
review.rating = rating
review.comment = comment
review.pub_date = datetime.datetime.now()
review.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
#?danger={{safety}}?name={{name}}?fav=1
#"beachProfile?danger='+danger+'?name='+marker.title+'" is this correct way???
return HttpResponseRedirect("beachProfile?danger='+beach.safety+'?name='+beach.beachname+'")
return render(request, 'users/beach.html', {'beach': beach, 'form': form})
在 beach.html 中,添加您的评论是一个按钮,用于转到表单以提交用户评论
<div id="reviews">
<h2>Add your Review</h2>
<form action="{% url 'add_review' beach.beach_id %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_form form layout='inline' %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Add
</button>
{% endbuttons %}
</form>
</div>
我不确定我在哪里错了,因为我还是新手来学习这些。请任何人都可以帮助解决这些错误。
我想知道发生 IntegrityError 的问题是因为我可能两次保存了任何海滩实例,但我检查了所有代码,我保存实例的唯一位置是 beachProfile 视图,在上面你可以看到代码。但我不知道为什么它是错误的。错误信息是:
Apply all migrations: admin, auth, beachprofile, contenttypes, sessions
Running migrations:
Applying beachprofile.0007_auto_20190411_0432...Traceback (most recent call last):
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\sqlite3\base.py", line 298, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: beachprofile_beach.beach_id
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 353, in execute
output = self.handle(*args, **options)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\commands\migrate.py", line 203, in handle
fake_initial=fake_initial,
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\operations\fields.py", line 84, in database_forwards
field,
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\sqlite3\schema.py", line 309, in add_field
self._remake_table(model, create_field=field)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\sqlite3\schema.py", line 274, in _remake_table
self.quote_name(model._meta.db_table),
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\base\schema.py", line 133, in execute
cursor.execute(sql, params)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\HP\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\sqlite3\base.py", line 298, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: beachprofile_beach.beach_id
在我将“海滩否则创建它”更改为之后,错误没有改变
beach = Beach.objects.filter(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
).first()
if beach is None:
beach = Beach.objects.create(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
)
所以我认为问题可能不在这里。我把我的 urls.py 放在上面。我还有其他 html:review_details.html 用于在评论列表中获取评论的详细信息,review_list.html 用于获取最新评论列表,以及 user_review_list.html(这只是添加带有评论用户名的标题以扩展 review_list)在评论列表中获取评论的详细信息(您可以通过单击海滩评论列表中的用户名来获取它)
同样在 review_detail.html 中:
<!--go back to the profile page bug here = no idea of fav number ??????-->>
<h2><a href="{% url '?danger={{review.beach.safety}}?name={{review.beach.beachname}}?fav=1' %}">{{ review.beach.beachname }}</a></h2>
单击海滩名称时,我想转到个人资料页面。但是重定向 url 可能也不正确,这与 add_reviews 函数有同样的问题。
解决方案
欢迎来到 StackOverflow!
看起来当您指定模型时,您的主键有一个默认值。主键必须是唯一的。因此,在您的default=1
约束下,如果未指定密钥,它将被设置为1
. 美妙之AutoField
处在于它将处理设置主键。
https://docs.djangoproject.com/en/2.2/ref/models/fields/#autofield
根据可用 ID 自动递增的 IntegerField。您通常不需要直接使用它;如果您没有另外指定,主键字段将自动添加到您的模型中。
所以我建议default=1
从你的模型的主键定义中删除
class Beach(models.Model):
beach_id = models.AutoField(primary_key=True)
...,
与评论相同:
class Review(models.Model):
review_id = models.AutoField(primary_key=True)
...,
因此,如果我了解您要执行的操作,我会看到此代码块存在一些问题。
beach = Beach(Beach.objects.get(), beachname=name, safety=testsafe, lat=latitude, lng=longitude)
if beach.beach_id == None and beach.beachname == None:
beach.save()
else:
pass
当您调用时,您正在内存beach = Beach(Beach.objects.get(), beachname=name, safety=testsafe, lat=latitude, lng=longitude)
中创建一个新模型并且不会设置,因为它尚未保存到您的数据库中。Beach
beach_id
看起来你想检查是否Beach
已经存在。
你可以这样做:
# check if beach exists
# first will return none if no records are returned
beach = Beach.objects.filter(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
).first()
if beach is None:
beach = Beach.objects.create(
beachname=name,
safety=testsafe,
lat=latitude,
lng=longitude,
)
如果我不理解您在这里尝试做什么,请随时详细说明。
推荐阅读
- cuda - cudaEventElapsedTime 和 nvprof 运行时
- postgresql - 我是否必须为 PostgreSQL 中的分区表的每个分区创建一个表
- javascript - 如何修复 CSS div 未正确对齐
- c# - 观察者不能捕获动态扩展方法中抛出的异常
- java - “NoSuchFieldError:qTESLA_I”与 JcaContentSignerBuilder
- java - Docker 容器中的 JAVA_HOME
- macos - SwiftUI 列表包含 Mac 上自动换行的文本
- c# - 以编程方式确定 Azure 资源的子资源
- java - Java 从 byte[] 到 char[] 的转换
- mpeg-dash - mpegdash文件的元数据提取